2012-09-10 59 views
1

我有一個使用JPA2/Hibernate和Spring @Transactional的JSF2應用程序。 UI中沒有@Transactional語句(支持bean),僅在服務層中。 (我在DAO中使用@Transactional(propagation = Propagation.MANDATORY)來確保每次調用都發生在一個事務中。)它的一切都很好,除了...爲什麼實體管理器需要清除()? - Spring3 @Transactional,JPA2/Hibernate3

當我打開並更新實體時事務服務方法,有時候檢索的實體是舊的。無關緊要的是它在同一個會話中是同一個用戶,偶爾JPA的「read」方法返回已經被(應該)已經被替換的陳舊實體。這難倒了我很長一段時間,但事實證明這是由實體管理器中的緩存引起的。 DAO用@Repository註釋,所以注入的EntityManager正在被重用。我曾預料當交易完成時,實體經理會自動清除。但事實並非如此。實體管理器通常會返回正確的值,但通常會返回並返回早期事務中的舊事務。

作爲一種解決方法,我在DAO讀取方法中添加了策略entityManager.clear()語句,但這很醜陋。實體管理員應在每次交易後清除。

有沒有人遇到過這個?有沒有合適的解決方案?每次交易後,實體經理能否被清除?

非常感謝。

我使用:org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean和org.springframework.orm.jpa.JpaTransactionManager

回答

1

@Transactional註解服務層的存在。使用@Transactional標記的服務方法無論從其中創建多少個DAO調用,都將遵守ACID屬性。

這意味着您無需將DAO方法註釋爲@Transactional。

我正在做類似的事情,這就是我做到這一點,我的數據是一致的。

試試看,看看你是否仍然收到不一致的數據。

+0

我想確保如果直接在現有事務之外調用DAO方法之一,則拋出異常。 DAO絕不能開始交易。我認爲這就是@Transactional(propagation = Propagation.MANDATORY)會做的事情。 – John

+0

不應該直接調用DAO。服務層訪問DAO層。控制器/端點應該訪問服務層。那麼爲什麼要考慮直接調用DAO。服務層將調用DAO。 –

+0

如果僅將@Transactional添加到DAO中,即沒有傳播= Propagation.MANDATORY,則它的行爲方式也是相同的。 –

0

你使用@PersistenceContext註釋(上述的EntityManager在DAO)與PersistenceAnnotationBeanPostProcessor豆組合(你沒有定義PersistenceAnnotationBeanPostProcessor豆如果你正在使用<context:annotation-config/><context:component-scan/> XML標籤)?如果沒有,我猜這是你問題的原因。

相關問題