CrudRepository的save方法返回一个bean,即使它没有被创建

时间:2012-12-17 10:46:55

标签: spring hibernate jpa spring-data spring-data-jpa

我正在使用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。

谢谢,

哈维

1 个答案:

答案 0 :(得分:4)

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