java - 使用 DAO 设计模式在 Hibernate 中进行事务管理

标签 java hibernate design-patterns transactions dao

我有很多表,对于每个表,我们都有 DAO 接口(interface)和 DAO 实现类。

示例 DAO 接口(interface)

public interface CancelPolicyDAO {

public CancelPolicy insertCancelPolicy(CancelPolicy cpdao)throws ChannelDispatcherException;

public CancelPolicy updateCancelPolicy(CancelPolicy cpdao)throws ChannelDispatcherException;

public void deleteCancelPolicy(CancelPolicy cpdao)throws ChannelDispatcherException;

public CancelPolicy findByCancelPolicyData(Integer id, Integer offSetUM, Integer nights, Float pOrAm, Byte isPercent)throws ChannelDispatcherException;

public CancelPolicy findByCancelPolicyId(Integer id)throws ChannelDispatcherException;
}

示例 DAO 实现类

public class CancelPolicyDAOImpl implements CancelPolicyDAO {

@Override
public CancelPolicy insertCancelPolicy(CancelPolicy bean) throws ChannelDispatcherException {

    Session ses = null;
    try {

        ses = HibernateConnector.getInstance().getSession();
        ses.save(bean);
        ses.flush();
        return bean;
    } catch (Exception e) {
        e.printStackTrace();
        throw new ChannelDispatcherException(DbUtil.getStackTraceMessage(e));
    } finally {
        if (ses != null) {
            try {
                ses.close();
            } catch (Exception er) {
                er.printStackTrace();
            }
        }
    }

}

@Override
public CancelPolicy updateCancelPolicy(CancelPolicy bean) throws ChannelDispatcherException {
    Session sess = null;

    try {

        sess = HibernateConnector.getInstance().getSession();
        sess.update(bean);
        sess.flush();
        return bean;
    } catch (Exception e) {
      e.printStackTrace();
        throw new ChannelDispatcherException(DbUtil.getStackTraceMessage(e));
    }

}

@Override
public void deleteCancelPolicy(CancelPolicy bean) throws ChannelDispatcherException {
    Session sess = null;

    try {

        sess = HibernateConnector.getInstance().getSession();
        sess.delete(bean);
        sess.flush();
    } catch (Exception e) {
     e.printStackTrace();
        throw new ChannelDispatcherException(DbUtil.getStackTraceMessage(e));
    }

}

@Override
public CancelPolicy findByCancelPolicyData(Integer id, Integer offSetUM, Integer nights, Float pOrAm, Byte isPercent) throws ChannelDispatcherException {

    Session ses = null;
    try {
        ses = HibernateConnector.getInstance().getSession();
        Query query = ses.createQuery("from CancelPolicy a where "
                + " a.cancelPolicyTypeId =:cancelPolicyTypeId  "
                + " and   a.offsetUnitMultiplier =:offsetUnitMultiplier  "
                + " and   a.nights =:nights  "
                + " and   a.percentOramount =:percentOramount "
                + " and   a.isPercent =:isPercent");

        query.setParameter("cancelPolicyTypeId", id);
        query.setParameter("offsetUnitMultiplier", (offSetUM));
        query.setParameter("nights", (nights));
        query.setParameter("percentOramount", pOrAm);
        query.setParameter("isPercent", isPercent);

        List queryList = query.list();
        if (queryList != null && queryList.isEmpty()) {
            return null;
        } else {
            return (CancelPolicy) queryList.get(0);
        }
    } catch (Exception e) {
       e.printStackTrace();
        throw new ChannelDispatcherException(DbUtil.getStackTraceMessage(e));
    } finally {
        if (ses != null) {
            try {
                ses.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

public CancelPolicy findByCancelPolicyId(Integer id) throws ChannelDispatcherException {

    Session ses = null;
    try {
        ses = HibernateConnector.getInstance().getSession();
        Query query = ses.createQuery("from CancelPolicy a where "
                + " a.id =:id  ");

        query.setParameter("id", id);

        List queryList = query.list();
        if (queryList != null && queryList.isEmpty()) {
            return null;
        } else {
            return (CancelPolicy) queryList.get(0);
        }
    } catch ( Exception e) {
       e.printStackTrace();
        throw new ChannelDispatcherException(DbUtil.getStackTraceMessage(e));
    } finally {
        if (ses != null) {
            try {
                ses.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}  

示例主要方法

 public static void main(String[] args)  {

       // How to handel Transaction in Hibernate ?
     CancelPolicyDAO cancelPolicyDAO = HibernateDAOFactory.getInstance().getCancelPolicyDAO();


     CancelPolicy insertCancelPolicy = cancelPolicyDAO.findByCancelPolicyData(2, 76, 25, 25.36f, 3);
    if(insertCancelPolicy==null){
        CancelPolicy cancelPolicy = new CancelPolicy();
    cancelPolicy.setCancelPolicyTypeId(1);
    cancelPolicy.setNights(2);
     insertCancelPolicy = cancelPolicyDAO.insertCancelPolicy(cancelPolicy);
    }
    Integer autoIncrementId = insertCancelPolicy.getId();

    AvailabilityDAO availabilityDAO =  HibernateDAOFactory.getInstance().getAvailabilityDAO();
    Availability availability = new Availability();
//        using  CancelPolicy autoIncrementId 
    availability.setId(autoIncrementId);
    availability.setCount(2);
    availability.setMaxLos(5);
    availabilityDAO.insertAvailability(availability);
    .
    .
    .
    .
    .


 }

现在我的问题是如何处理 DAOImpl 中的事务? 我应该将 session 对象作为每个 DAOImpl 的参数传递还是有更好的方法

最佳答案

虽然使用 Spring 可能是添加事务管理的最佳方式,但即使不重构所有代码库,您仍然可以解决这个问题。

您需要做的是设置如下配置:

hibernate.current_session_context_class=thread

您的 DAO 应该通过以下方式访问 session :

[SessionFactory.getCurrentSession()][1];

您仍然需要在服务层中声明事务边界:

Session sess = factory.openSession();
Transaction tx = null;
try {
    tx = sess.beginTransaction();

    dao1.find();
    dao2.save(entity);

    tx.commit();
}
catch (RuntimeException e) {
    if (tx != null) tx.rollback();
    throw e;
}
finally {
    sess.close();
}

DAO1 和 DAO2 将使用相同的 Hibernate Session 和相同的 Transaction。

为了避免这种冗长的事务管理代码处理,您可以编写一个简单的 TransactionManager 实用程序,例如:

public static abstract class TransactionCallable<T> {
    public abstract T execute();
}

public class TransactionManager {   
    public static <T> T doInTransaction(TransactionCallable<T> callable) {
        T result = null;
        Session session = null;
        Transaction txn = null;
        try {
            session = sf.openSession();
            txn = session.beginTransaction();

            result = callable.execute();
            txn.commit();
        } catch (RuntimeException e) {
            if ( txn != null && txn.isActive() ) txn.rollback();
            throw e;
        } finally {
            if (session != null) {
                session.close();
            }
        }
        return result;
    }
}

这就是服务的样子:

TransactionManager.doInTransaction(new TransactionCallable<Void>() {
    @Override
    public Void execute() {
        dao1.find();
        dao2.save(entity);
    }
});

关于java - 使用 DAO 设计模式在 Hibernate 中进行事务管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27170089/

相关文章:

java - 从不同的模块 Autowiring bean

MySQL 和 hibernate : performance of left outer join vs multiple selects

java - 获取 com.sun.jersey.api.client.ClientHandlerException : while generating Docusign API token

java - Spring Data JPA 无法确定属于同一类对象的属性的类型

java - 如何在两个虚拟节点之间的双向链表的开头添加一个节点?

java - 构建失败,并带有异常(:android:signingConfigWriterDebug)

java - 无法使用请求结果类型为具有多个返回的查询创建类型化查询

python - 可扩展程序的良好设计模式

java - 最佳工厂实现

javascript - 使用变量作为 Foo.prototype 的简写