我正在使用Spring(3.11)数据/存储库和JPA(2.0)/ Hibernate(3.5.6),我有一个与CrudRepository的保存方法有关的问题。
我所拥有的全球服务如下:
@Override
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
public MyBean createMyBean(MyBean myBean) {
// 1)
// myBean does not have PK, it will be generated via sequence
MyBean myBean = myBeanRepository.save(myBean);
// 2)
// sends event to queue
syncEventProducer.sendSyncEvent(....);
return myBean;
}
我的问题很简单:我故意插入一个不满足表要求的某个myBean(通常我设置为null,在DB中创建为非null的列)然后异常(例如DataIntegrityViolationException)是在调用1)内部生成,但2)仍然执行。那是为什么?
MyBeanRepository是这样的:
public interface MyBeanRepository extends CrudRepository<MyBean, Integer> {
}
在代码中挖掘一点我看到与我的存储库相关的SimpleJpaRepository确实返回了我的bean的新PK,即使这不应该发生。
当然最后整个事务都是回滚的,但我仍然无法理解为什么myBeanRepository.save(myBean)“吞下”异常并返回一个带有新PK的新bean。
谢谢,
哈维
答案 0 :(得分:4)
我认为这是因为当您在Transactional
方法上有createMyBean
注释时,事务只会在方法结束时完成。 Hibernate session.flush()仅在提交事务时调用,如果没有显式调用它。因此,insert语句实际上是在2之后对DB执行的,只有在那时你才会抛出异常。