我正在尝试使用Hibernate和Spring DataSourceTransactionManager来处理提交和回滚功能,但我可能会得到一些东西。
在使用Spring DataSourceTransactionManager之前,这是我的DAO类之一
package com.springgestioneerrori.DAO;
public class UtenteDAO extends DAOBase{
public void salvaUtente(Utente utenteIn) throws DAOException{
Session session = getHibernateSession(); //from this method I get Hibernate SessionFactory
try{
session.beginTransaction();
session.saveOrUpdate(Object);
session.getTransaction().commit();
}
catch(Exception e){
session.getTransaction().rollback()
}
}
}
这是给我sessionFactory
的类 private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new AnnotationConfiguration().configure().buildSessionFactory();
}
catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdown() {
getSessionFactory().close();
}
public Session getHibernateSession (){
Session session = HibernateUtil.getSessionFactory().openSession();
return session;
}
现在我试图以声明的方式使用DataSourceTransactionManager。在互联网上的一些例子后,我写了这个:
<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager" />
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="salvaUtente"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="userDaoTxPointcut" expression="execution(* com.springgestioneerrori.DAO.UtenteDAO.salvaUtente(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="userDaoTxPointcut" />
</aop:config>
现在,我应该在方法salvaUtente()中编写什么来执行许多插入,例如像这些
session.saveOrUpdate(User);
session.saveOrUpdate(UserCredentials);
session.saveOrUpdate(UserOtherDetails);
让Spring处理commint和rollback?
答案 0 :(得分:5)
首先,您使用的是错误的事务管理器。 DataSourceTransactionManager
不是Hibernate,而是普通的JDBC。如果您使用普通的Hibernate,请使用HibernateTransactionManager
。 (假设你在这里使用Hibernate 4!)。
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
现在我还建议使用@Transactional
代替<tx:advice />
和<aop:config />
块。使您的配置更容易。只需删除2个提到的块并替换为<tx:annotation-driven />
。
<tx:annotation-driven />
现在你的代码错了,因为你自己开始交易。使用@Transactional
注释您的方法(在添加上述内容之后)并删除您的交易处理代码。
@Transactional
public void salvaUtente(Utente utenteIn) throws DAOException{
Session session = getHibernateSession(); //from this method I get Hibernate SessionFactory
session.saveOrUpdate(Object);
}
现在,我不知道您的getHibenateSession
方法有何功能,但请确保您不要在openSession
上使用SessionFactory
来获取会话。请改用getCurrentSession
。
protected Session getHibernateSession() {
return sessionFactory.getCurrentSession();
}
您当前的BaseDAO
课程存在缺陷。删除buildSessionFactory
并删除static final
。让Spring配置并注入SessionFactory
。
public abstract class BaseDAO {
@Autowired
private SessionFactory sessionFactory;
protected Session getHibernateSession() {
return sessionFactory.getCurrentSession();
}
}
在您的配置中添加LocalSessionFactoryBean
。
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
... Other Hibernate Properties
</bean>
基本上只需要这一切。这也在the Spring Reference guide中详细解释。我强烈建议阅读。
答案 1 :(得分:0)
我建议
@Transaction(rollbackFor = {if you need to rollback on certain checked exception})
salvaUtente()
除非另有说明,否则只对未经检查的异常进行事务处理。
如果交易中的salvaUtente在任何时候都有异常,那么一旦该方法存在,交易将被提交
答案 2 :(得分:0)
HibernateTransactionManager也可以管理数据源上的事务。我们需要在HibernateTransactionManager中注入数据源,它对于Hibernate和普通的旧SQL均适用。
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager>
<property name="sessionFactory" ref="sessionFactory"/>
<property name="dataSource" ref="dataSource"/>
</bean>
希望这对您有用。
(我知道这已经很晚了,但可能会帮助某人登陆此帖子)