Reputation: 101
I have a JSF2 application that is using JPA2/Hibernate with Spring @Transactional. There are no @Transactional statements in the UI (backing beans), only in the service layer. (I am using @Transactional(propagation=Propagation.MANDATORY) in the DAOs to ensure every call occurs in a transaction.) It's all works very nicely, except...
When I am opening and updating the entities through the transactional service methods, Sometimes the retrieved entities are old. It doesn't matter that it's the same user in the same session, occasionally, the JPA "read" methods return older stale entities that have (should have) already been replaced. This stumped me for quite a while, but it turns out it is caused by caching in the Entity Manager. The DAOs are annotated with @Repository, so the injected EntityManager is being reused. I had expected that when the transaction completed, the entity manager would automatically be cleared. But that is not the case. Usually the Entity Manager returns the correct value, but often it reaches back and returns an old one from an earlier transaction instead.
As a workaround, I have sprinkled strategic entityManager.clear() statements in the DAO read methods, but that is ugly. The entityManagers should be cleared after each transaction.
Has anyone experienced this? Is there a proper solution? Can the entity manager be cleared after each transaction?
Thanks very much.
I am using: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean and org.springframework.orm.jpa.JpaTransactionManager
Upvotes: 0
Views: 669
Reputation: 2073
Do you use @PersistenceContext
annotation (above EntityManager in DAO) combined with PersistenceAnnotationBeanPostProcessor
bean (you don't have to define PersistenceAnnotationBeanPostProcessor
bean if you are using <context:annotation-config/>
and <context:component-scan/>
XML tags) ? If not, I guess this is the reason of your problems.
Upvotes: 0
Reputation: 119
The @Transactional annotation exists in the service layer. The service methods marked with @Transactional will adhere to the ACID properties no matter how many DAO calls are made from within it.
This means that you need not annotate the DAO methods as @Transactional.
I am working on something similar and this is how I have done it and my data is consistent.
Try it this and see if you are still getting inconsistent data.
Upvotes: 1