1

我将 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 的列设置为 null)然后在内部产生异常(例如 DataIntegrityViolationException)在调用 1) 但 2) 仍然被执行。这是为什么?

MyBeanRepository 是这样的:

public interface MyBeanRepository extends CrudRepository<MyBean, Integer> {

}

在代码中挖掘一点我已经看到与我的存储库相关的 SimpleJpaRepository 确实返回了带有新 PK 的我的 bean,即使这不应该发生。

当然,最后整个事务被回滚,但我仍然不明白为什么 myBeanRepository.save(myBean) 会“吞下”异常并返回一个带有新 PK 的新 bean。

谢谢,

哈维

4

1 回答 1

4

我认为这是因为当您在方法Transactional上有注释时createMyBean,事务仅在方法结束时完成。Hibernate session.flush() 仅在事务提交时调用,如果您没有显式调用它。所以插入语句实际上是在 2 之后对 DB 执行的,只有到那时你才会抛出异常。

于 2012-12-17T16:25:58.003 回答