我有很多表,对于每个表,我们都有DAO接口和DAOImplementation类。
示例DAO接口
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;
}
示例DAOImplementation类
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中的Transaction? 我应该将Session Object作为每个DAOImpl的参数传递,还是有更好的方法
答案 0 :(得分:10)
我强烈建议不要重新发明轮子;使用现有的,健壮的和经过测试的代码。
评论已经提到了AOP和Spring框架。这是不可能的。 Spring框架甚至有一个名为Spring Data的子项目,它允许您以声明方式定义查找器方法(如findByCancelPolicyData
)。
这将为您节省大量的工作。
如果由于任何原因你不想/不可能使用Spring,你仍然可以阅读基本框架和提到的Spring Data的非常好的文档,以获得关于交易的许多优秀想法(通过AOP ),代码重用(通过通用DAO)或API设计。不要错过这个读物。
答案 1 :(得分:8)
虽然使用Spring可能是添加事务管理的最佳方式,但即使不重新考虑所有代码库,您仍然可以解决它。
您需要做的是设置以下配置:
hibernate.current_session_context_class=thread
您应该通过以下方式访问会话:
[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);
}
});
答案 2 :(得分:2)
如果您有 Web应用程序并且您没有在项目中使用spring进行会话管理,我建议使用拦截器来分隔DAO之外的会话处理逻辑。您可以参考下面提到的相同文章。请注意,这种方法存在某些CON,但我们发现它是我们案例中最方便的方法。
下面是我们如何在View模式中使用Generics的Open Session的示例,我们可以为您提供类,
public class CancelPolicyDAOImpl extends GenericDAOImpl<CancelPolicy, Long> implements CancelPolicyDAO {
@Override
public CancelPolicy insertCancelPolicy(CancelPolicy bean) throws ChannelDispatcherException {
try {
// save method is implemented in GenericDAOImpl described below.
return save(bean);
} catch (Exception e) {
e.printStackTrace();
}
}
//remaining methods
}
在上面的代码中使用了在GenericHibernateDAOImpl中实现的save方法,如下所示。您可以使用Google for GenericHibernateDAOImpl类并抓取它,其中包含许多其他基本操作方法。
public abstract class GenericDAOImpl<T, ID extends Serializable> {
private Session session;
public T save(final T entity) {
Transaction trans = null;
try {
trans = session.beginTransaction();
session.saveOrUpdate(entity);
session.flush();
trans.commit();
} catch (Exception ex) {
rollBackTransaction(trans);
// you might require to throw error again here
}
return entity;
}
//in case any complex operations required you can get core session object from this method
protected Session getSession() {
return sessionFactory.getCurrentSession();
}
}
现在回到你关于在哪里获得会话的问题,如上所示GenericHibernateDAOImpl会话是通过getCurrentSession方法从singleton sessionFactory中检索的。请注意,您需要在获取当前会话之前运行活动事务,您可以在拦截器中使用该链接(本文开头提供的链接)。
请告诉我。
答案 3 :(得分:0)
不需要使用框架,CancelPolicy对象是主要对象,它应该具有休眠功能(级联)检查链接(Cascading life cycle)
所以你用所有必需的关系填充CancelPolicy对象,并说保存,它将保存相关对象的所有图形。