package sample;

import java.util.Iterator;
import java.util.List;

import entity.Employee;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.LockMode;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.Transaction;
import net.sf.hibernate.cfg.Configuration;

/**
 * Hibernate版従業員DataAccessObject
 */
public class HibernateEmployeeDAO {
    /**
     * セッション
     */
    private Session session;
    
    /**
     * コンストラクタ
     * @param session セッション
     */
    public HibernateEmployeeDAO(Session session){
        this.session = session;
    }
    
    /**
     * 指定したIDの従業員を取得する
     * @param id 従業員ID
     * @param lock 行ロックを行うかどうか
     * @return Employee
     * @throws SQLException
     */
    public Employee get(Integer id, boolean lock) throws HibernateException{
        LockMode lockMode = LockMode.NONE;
        if( lock ){
            lockMode = LockMode.UPGRADE;
        }
        return (Employee) session.get(Employee.class, id, lockMode);
    }
    
    /**
     * 部門名に対応する従業員のリストを返す
     * @param departmentName 部門名
     * @param lock 行ロックを行うかどうか
     * @return List
     * @throws HibernateException
     */
    public List getListByDepartmentName(String departmentName, boolean lock) throws HibernateException{
        Query query = session.getNamedQuery("entity.Employee.getListByDepartmentName");
        query.setParameter("departmentName", departmentName);
        if( lock ){
            query.setLockMode("e", LockMode.UPGRADE);
        }

        return query.list();
    }

    /**
     * 従業員を挿入する
     * @param emp 従業員
     * @throws HibernateException
     */
    public void insert(Employee emp) throws HibernateException{
        session.save(emp);
    }
    
    /**
     * 従業員を削除する
     * @param emp 従業員
     * @throws HibernateException
     */
    public void delete(Employee emp) throws HibernateException{
        session.delete(emp);
    }

    /**
     * 従業員を更新する
     * @param emp 従業員
     * @throws HibernateException
     */
    public void update(Employee emp) throws HibernateException{
        //session.update(emp);
    }
    
    /**
     * サンプルコードメイン
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception{
        Configuration cfg = null;
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction transaction = null;
        
        try{
            //構成情報の読み込み
            cfg = new Configuration().configure();
            //セッションファクトリをビルド
            sessionFactory = cfg.buildSessionFactory();
            //セッションを取得
            session = sessionFactory.openSession();
            //トランザクションを開始
            transaction = session.beginTransaction();
            
            HibernateEmployeeDAO dao = new HibernateEmployeeDAO(session);
            //IT部門の従業員のリストを取得
            List employees = dao.getListByDepartmentName("IT", true);
            Iterator ite = employees.iterator();

            //給与を1000円値上げ
            while(ite.hasNext()){
                Employee emp = (Employee) ite.next();
                int salary = emp.getSalary().intValue();
                emp.setSalary( new Integer(1000 + salary) );
                
                //従業員の更新
                dao.update(emp);
            }

            //コミット
            transaction.commit();
        }catch (Exception e){
            //ロールバック
            if(transaction != null){
                transaction.rollback();
            }
            e.printStackTrace();
        }finally{
            //常にセッションを閉じる
            if(session != null){
                session.close();
            }
        }
    }
}