Reputation:
I am using Spring (3.11) data/ repositories together with JPA (2.0)/ Hibernate (3.5.6) and I have an issue to do with the CrudRepository's save method.
The global service I have is as follows:
@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;
}
My problem is simple: I am inserting on purpose a certain myBean that does not satisfy the table requirements (typically I am setting as null a column which was created as not null in the DB) then an exception (e.g. DataIntegrityViolationException) is being produced internally in the call 1) but 2) still gets executed. Why is that?
MyBeanRepository is like this:
public interface MyBeanRepository extends CrudRepository<MyBean, Integer> {
}
Digging a little bit in the code I have seen that the SimpleJpaRepository related to my repository returns indeed my bean with a new PK even though that should not have happened.
Of course at the end the whole transaction is rollbacked but still I do not get to understand why myBeanRepository.save(myBean) "swallows" the exception up and returns instead a new bean with a new PK.
Thanks,
Javi
Upvotes: 1
Views: 3980
Reputation: 3142
I think it is because when you have Transactional
annotation on your createMyBean
method, the transaction only completes at the end of the method. Hibernate session.flush() is only called when transaction is committed, if you don't call it explicitly. So the insert statement is actually executed against DB after 2, only by then you have the exception thrown.
Upvotes: 3