在Spring和Hibernate中使用TransactionProxyFactoryBean

时间:2015-04-28 15:09:47

标签: java spring hibernate orm configuration

我有一个旧项目,我试图升级到spring 4 / hibernate 4.

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

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

mVerboseExec

<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都被定义为:

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

和DAO定义如下:

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

PersonDaoImpl(以及所有其他DAO)有许多方法看起来像这样(所有DAO都扩展了HibernateDaoSupport):

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

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

这是我采取的步骤:

  • 只需从DAO方法中删除它们 - 不要扩展HibernateDaoSupport,删除HibernateTemplate回调。这看起来像:

        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;
    }
    

当然这给了我编译时错误,因为&#39; getSessionFactory&#39;是基类的一部分&#39; HibernateDaoSupport&#39;我刚刚删除了。

  • 所以我实施了一个&#39; MyHibernateDaoSupport&#39;类,并让我的DAO扩展了。它看起来像:

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

    }

现在我可以构建,部署和运行,并点击此错误消息:

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() {
    }

我该如何使这项工作?

  • 简单来说,什么是&#39; hibernateCallback()&#39;以及它的内部类实际上正在做什么?

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

我已经尝试过标记我的客户服务&#39; (使用@transactional调用&#39; PersonDao&#39;)的业务逻辑对象但是(A)我看到相同的错误,而且(B)我真的更喜欢能够以编程方式执行此操作,以减少代码工作方式的变化规模。我也尝试将事务放在DAO级别,并遇到了同样的问题。

道歉,如果这对于Stack溢出格式来说太详细了。

1 个答案:

答案 0 :(得分:2)

  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

  6. 这是详细的逐步tutorial for configuring Spring and Hibernate 4