分享

spring hibernate的事务处理(使用hibernate原有的sessionFactory)

 minwh 2006-07-30
spring+hibernate的事务处理
2006-03-24 17:11:13
  
我有以前struts+hibernate的一些代码。现在想加入spring,但是既然spring是为了分离程序间的耦合,当然,也不能和spring结合的太紧蜜。
所以,我尽量不在manager和DAO里使用spring的类。于是写了下面的几个基础类,希望以后即使修改也不用改动太大。
 
public interface BaseDAO {
 public Long add(Object object) throws HibernateException;
}
 
 
public class BaseDAOImpl  extends HibernateDaoSupport {
 
 //这里是希望spring在构造这个类时将sessionFactory传递给HibernateDaoSupport.setSessionFactory(),并初始化一个session对象
 protected Session session =null;
 public BaseDAOImpl(SessionFactory sessionFactory) {
 this.setSessionFactory(sessionFactory);
 this.session = this.getSession();
 }

 public Long add(Object object) throws HibernateException{
  Long reval=null;
  reval=(Long)session.save(object);
  return reval;
 }
public interface BaseManager {
 public Long add(Object object) throws BusinessLogicException, HibernateException;
}
 
public class BaseManagerImpl {
}
 
具体的UserDAO和UserManager如下:
public interface UserDAO extends BaseDAO{
}
public interface UserManager extends BaseManager{
}
public class UserDAOImpl extends BaseDAOImpl implements UserDAO{
}
public class UserManagerImpl extends BaseManagerImpl implements UserManager{

 public Long add(Object object) throws BusinessLogicException, HibernateException {
  return userDAO.add(object);
 }
}
 
spring配置文件如下:
<beans>
 <description>bean test</description>
  
 <bean id="hibernateSessionFactory" factory-method="getSessionFactory"
   class="huye.common.util.HibernateUtil" />
 
 <bean id="hibernateTransactionManager"
  class="org.springframework.orm.hibernate.HibernateTransactionManager">
  <property name="sessionFactory">
   <ref local="hibernateSessionFactory" />
  </property>
 </bean>
 <bean id="UserDAO" class="huye.user.proxy.impl.UserDAOImpl">
  <constructor-arg><ref local="hibernateSessionFactory"/></constructor-arg>
 </bean>
    <bean id="UserManagerTarget" class="huye.user.proxy.impl.UserManagerImpl">
    </bean>
 <bean id="UserManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  <property name="transactionManager">
   <ref bean="hibernateTransactionManager" />
  </property>
  <property name="target">
   <ref local="UserManagerTarget" />
  </property>
  <property name="proxyTargetClass">
   <value>false</value>
  </property>

  <property name="transactionAttributes">
   <props>
    <prop key="add*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>
    <prop key="update*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>
    <prop key="delete*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>
    <prop key="get*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>
   </props>
  </property>
 </bean>

</beans>
 
然望能通过这样的结构达到即使以后去掉了spring,我只需要修改baseDAOImpl和BaseManagerImpl类就可以了。
 
可是运行后发现事务没有提交,但也不出现错误提示。
连续试验了一天,并使用sqlserver事件查看器,才发现问题。原来,add时同时建立了两个连接,连接1没有执行SQL语句,但提交了事务,连接2只执行了SQL语句。
可能是因为我把sessionFactory放在了DAO的构造方法里,而不是setter里。
把BaseDAOImpl改造一下,构造方法去掉,加入
 public void setSessionFactory2(SessionFactory sessionFactory){
  this.setSessionFactory(sessionFactory);
  this.session = this.getSession();
  System.out.println("session=" + session);
  
 }
并在spring配置文件里做相应配置。
这次发现虽然和数据库只建立了一个连接,但是却没有执行SQL语句。
奇怪了。
把add方法改一下:
 public Long add(Object object) throws HibernateException{
  Long reval=null;
  reval=(Long)getSession().save(object);
  return reval;
 }
这次才成功,数据正确保存。
但是这样的话,我所有的DAO都要把session.method改成getSession().method。
这也太麻烦了。
只是很奇怪,明明只有一个session,不知道为什么不执行呢?
等下次解决吧。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多