2017-02-12 93 views
1

当我使用spring + hibernate时,HQL语句不会回滚,但是session.saveOrUpdate()会;spring-hibernate transactional dont rollback

UserService

@Service 
@Transactional(rollbackFor=Exception.class) 
public class UserService { 

    @Autowired 
    private BaseDao dao; 

    public int updateTest(){ 
     int i = dao.updateUser(); 
     int t = 1/0; 
     return i; 
    } 
} 

BaseDao

@Repository 
public class BaseDao { 

    @Autowired 
    private SessionFactory sessionFactory; 

    private Session getSession(){ 
     return sessionFactory.getCurrentSession(); 
    } 

    public int updateUser(){ 
     int i = 0; 
     /* String sql = "from Student where name = 'dengbojing'"; 
     Query query = this.getSession().createQuery(sql);*/ 
     Student s = new Student(); 
     s.setId(1); 
     s.setAddress("1"); 

     Query query = this.getSession().createQuery("update Student s set s.address = '1'"); 


     query.executeUpdate(); 

     //this.getSession().update(s); 
     return i; 
    } 

} 

配置类

@Configuration 
@EnableConfigurationProperties(HibernateProperties.class) 
@EnableTransactionManagement(proxyTargetClass=true) 
public class HibernateConfig { 
    @Autowired 
    private HibernateProperties config; 


    @Bean(name="sessionFactory") 
    public LocalSessionFactoryBean localSessionFactoryBean(){ 
     LocalSessionFactoryBean bean = new LocalSessionFactoryBean(); 
     bean.setDataSource(dataSource()); 
     bean.setHibernateProperties(config.getHibernateProperties()); 
     bean.setPackagesToScan(config.getPackageToScan()); 
     return bean; 
    } 

    @Bean 
    public DataSource dataSource(){ 
     DruidDataSource source = new DruidDataSource(); 
     source.setDriverClassName(config.getDatasource().getDriverClassName()); 
     source.setUsername(config.getDatasource().getUsername()); 
     source.setUrl(config.getDatasource().getUrl()); 
     source.setPassword(config.getDatasource().getPassword()); 
     return source; 
    } 

    @Bean 
    public HibernateTransactionManager txManager(){ 
     HibernateTransactionManager manager = new HibernateTransactionManager(); 
     manager.setSessionFactory(localSessionFactoryBean().getObject()); 
     manager.setDataSource(dataSource()); 
     return manager; 
    } 

} 

Spring的事务不支持HQL语句,问题plag请教我2天,我看到有人有类似的问题,但没有解决问题

+0

我做了一些测试,它为我工作..什么是你的春天/ hib版本? –

+0

真的吗?你能过去你的代码吗?春季4.2.5和休眠4.3.11 – Deng

+0

只是为了确保..当你做execureUpdate并在此后抛出一个异常..更新仍然存在数据库中吗? –

回答

0

我已经做了一些测试,完全相同的版本和配置。我不得不说,更新永远不会在数据库中持久。

作为一种解决办法,如果你能以这种方式实现你的功能..尝试:

  • 找到期望的人的实体
  • 更新所需的字段
  • 不要调用上的任何其他方法会话对象之后..只需将其留给框架来更新事务提交上的更改。

Person person = session.get(Person.class, 1); 

person.setAddress("1") 
// other fields updated 

return i; 

现在,无需使用executeUpate()明确批量更新就没有机会了一个隐含的由供应商提交。这是理论所以检查出来。

+0

是的,如果你不使用excuteUpdate()不是问题,但是在某些场景下需要使用HQL或SQL语句 – Deng

+0

我想知道,但是我写SQL或HQL的事务不行,或者hibernate本身做不支持 – Deng

+0

尝试删除该属性的回滚...这是多余的在你的情况下无论如何 –