2015-04-28 93 views
12

我有一个旧项目,我试图升级到春季4 /休眠4.在hibernate 4/spring 4中使用TransactionProxyFactoryBean?

我们使用this方法来配置我们的交易。

也就是说,在XML我们定义了一个事务管理器,如:

<bean id="abstractTransactionProxy" 
abstract="true" 
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
<property name="transactionManager" ref="hibernateTransactionManager"/> 
<property name="transactionAttributes"> 
    <props> 
     <prop key="create*">PROPAGATION_REQUIRED</prop> 
     <prop key="update*">PROPAGATION_REQUIRED</prop> 
     <prop key="delete*">PROPAGATION_REQUIRED</prop> 
     <prop key="*">PROPAGATION_SUPPORTS,readOnly</prop> 
    </props> 
</property> 

<bean id="MySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource"  ref="myDataSource" /> 
    <property name="configLocation" value="WEB-INF/hibernate.cfg.xml" /> 
</bean> 

,然后我们每一个服务豆类等定义:

<bean id="customerService" parent="abstractTransactionProxy"> 
    <property name="target" ref="customerTarget"/> 
    <property name="personDAO" ref="personDAO" /> 
</bean> 

和DAO的像定义:

<alias name="personDaoImpl" alias="personDAO"/> 
<bean id="personDaoImpl" 
    class="com.foo.bar.hibernate.PersonDaoImpl"> 
    <property name="sessionFactory" ref="MySessionFactory" /> 
</bean> 

PersonDaoImpl(和所有其他的DAO)有许多方法看起来像这样的(所有的DAO的扩展的HibernateDaoSupport):

public List<Person> getPersonByCriteria(final String criteria) { 
    List<Person> results = 
     (List<Person>) this.getHibernateTemplate().executeFind(new HibernateCallback<List<Person>>(){ 

     public List<Person> doInHibernate(Session session) throws HibernateException, SQLException { 
      List<Person> results = (List<Person>) session.createQuery(MYSQLHERE).setString("criteria", criteria).list(); 
      return results; 
     } 
    }); 
    return results; 
} 

现在的问题在这一点上我面对的是摆脱我们对从HibernateDaoSupport扩展我们的DAO的依赖,以及扩展,使用它的HibernateTemplate帮助对象。

下面是我所采取的步骤:

  • 只需从DAO方法将其删除 - 不延长的HibernateDaoSupport,取出的HibernateTemplate回调。这看起来像:

    public List<Person> getPersonByCriteria(final String criteria) { 
         List<Person> results = (List<Person>) getSessionFactory().getCurrentSession().createQuery(MYSQLHERE).setString("criteria", criteria).list(); 
    
         return results; 
        } 
    

当然是因为“了getSessionFactory”是,我只是删除了基类的HibernateDaoSupport“的一部分,这给了我编译时错误。

  • 所以我实现了'MyHibernateDaoSupport'类,并且让我的DAO扩展了它。它看起来像:

    public class MyHibernateDaoSupport { 
    
        private SessionFactory sessionFactory; 
        protected Session session; 
        protected static Logger logger = Logger.getLogger(MyHibernateDaoSupport.class); 
    
        public void setSessionFactory(SessionFactory sessionFactory) { 
         this.sessionFactory = sessionFactory; 
         session = this.sessionFactory.getCurrentSession(); 
        } 
    
        public SessionFactory getSessionFactory() { 
        return this.sessionFactory; 
        } 
    
        public Session getHibernateTemplate() { 
         session = this.sessionFactory.getCurrentSession(); 
         return session; 
        } 
    
        public MyHibernateDaoSupport() { 
        } 
    

    }

现在我可以构建,部署和运行,我打这个错误信息:

No session available in this thread 

我怎样才能使这项工作?

  • 简单来说,什么是 'hibernateCallback()',它实际上做anoymous内部类?

  • 如何在不使用HibernateDaoSupport和HibernateTemplate类的情况下像以前一样使项目的事务工作?

我试图用我的标签“的CustomerService”(即所谓的“PersonDao的”业务逻辑对象)@Transactional但(A)我看到不管了同样的错误和(B)我真的很喜欢能够以编程方式执行此操作,以减少代码现在工作方式的变化规模。我也尝试将交易放在DAO层面,并且遇到了同样的问题。

道歉,如果这是太多的细节堆栈溢出格式。

回答

1
  1. 您需要SessionFactory的注入到你的DAO类:

    @Repository 
    public class PersonDAOImpl implements PersonDAO { 
    
        @Autowired 
        private SessionFactory sessionFactory; 
    
        public List<Person> getPersonByCriteria(final String criteria) { 
         List<Person> results = (List<Person>) getSessionFactory().getCurrentSession().createQuery(MYSQLHERE).setString("criteria", criteria).list(); 
         return results; 
        } 
    } 
    
  2. 添加@Transactional到您的服务方法

  3. 添加HibernateTransactionManager

  4. 指导Spring使用声明性事务:

    <tx:annotation-driven transaction-manager="transactionManager"/> 
    
  5. 确保您使用LocalSessionFactoryBean创建了一个SessionFactory

这里有一个详细的一步一步的tutorial for configuring Spring and Hibernate 4