簡體   English   中英

不調用更新方法的事務性保存

[英]Transactional saves without calling update method

我有一個用@Transactional 注釋的方法。 我從我的 Oracle DB 中檢索一個對象,更改一個字段,然后從該方法返回。 我忘了保存對象,但發現數據庫無論如何都會更新。

應用上下文

<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

我的方法

@Transactional
public void myMethod(long id) {
    MyObject myObj = dao.getMstAttributeById(id);
    myObj.setName("new name");
    //dao.update(myObj);
}

我的問題是為什么 MyObject 會被持久化到數據庫?

因為休眠會自動檢測對持久實體所做的更改並相應地更新數據庫。 此行為記錄在 hibernate 參考手冊的第 11 章中。 相關部分內容如下:

Hibernate 定義並支持以下對象狀態:

  • Transient - 如果一個對象剛剛使用 new 運算符實例化,則它是瞬態的,並且它不與 Hibernate Session 相關聯。 它在數據庫中沒有持久表示,也沒有分配標識符值。 如果應用程序不再持有引用,垃圾收集器將銷毀瞬態實例。 使用 Hibernate Session 使對象持久化(並讓 Hibernate 處理需要為此轉換執行的 SQL 語句)。

  • 持久性- 持久性實例在數據庫中具有表示形式和標識符值。 它可能剛剛被保存或加載,但是,根據定義,它在 Session 的范圍內。 Hibernate 將檢測對處於持久狀態的對象所做的任何更改,並在工作單元完成時將狀態與數據庫同步。 開發人員不執行手動 UPDATE 語句,或當對象應變為瞬態時 DELETE 語句。

  • Detached - 分離的實例是一個已經持久化的對象,但它的 Session 已經關閉。 當然,對對象的引用仍然有效,並且在這種狀態下甚至可能會修改分離的實例。 一個分離的實例可以在稍后的時間點重新附加到一個新的 Session,使其(以及所有修改)再次持久化。 此功能為需要用戶思考時間的長時間運行的工作單元啟用編程模型。 我們稱它們為應用事務,即從用戶的角度來看的一個工作單元。

如果您使用的是 JPA,那么規范說明如果您的實體處於托管狀態(這就是您通過在活動事務中從 DAO 獲取數據來執行的操作),對它所做的所有更改都將反映在事務提交期間的數據庫。

所以,換句話說-這並不重要,如果你調用更新操作或不是因為事務提交將刷新對數據庫的更改。

我發現阻止自動更新數據庫是一個兩步過程。

步驟一::

getSession().setFlushMode(FlushMode.MANUAL) // [FlushMode.NEVER is depracated in 4.x]

步驟二:

getSession().clear(); //This will actually discard all changes

我用@Transactional(readOnly = true)來解決它

對於 JPA,調用entityManager.detach(entity)以避免自動刷新。 但是你需要注意分離的實體會在延遲獲取、級聯更新等之后失去 ORM 的魔力。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM