2013-12-17 111 views
3

如果我進行回滾,會話中的實體會發生什麼?交易前他們是否回到狀態?特別是他們獲得新ID嗎?回滾後JPA/Hibernate中的實體狀態和實體ID值

例子:

session.startTransaction(); 
Entity e = new Entity(); //e.id == null 
session.save (e);  //suppose it was ok 
session.rollback();  // e.id == ??? 

更新

我做了Hibernate的4個測試。在測試後,實體已經成爲一個新的ID。

+0

你還測試過嗎?它有用嗎?你還試圖在rollback()之前做一個flush()(這樣你就可以得到一個ID)? –

+0

@AndreiI我已經用Hibernate 4測試過了。這個id被分配給實體,並且在回滾後沒有改變。 – Tony

回答

5

我會簡單地從JPA實現引用(3.3.2事務回滾):

對於這兩個事務範圍和擴展的持久化上下文, 事務回滾導致所有預先存在的託管實例和已刪除的實例[31]分離。實例的狀態將爲 事務處於 回退點的實例狀態。事務回滾通常會導致持久性上下文在回滾點處處於不一致狀態。特別地,版本屬性和生成狀態的狀態(例如,生成主鍵的 )可能不一致。以前由持久性上下文管理的 (包括在該事務中持久化的新實例 )的實例因此可能不是 ,與其他分離對象相同 - 例如, 傳遞給合併時可能會失敗操作。[32]

這實際上意味着,這取決於你是否有或沒有的ID權調用em.rollback()(這取決於FlushMode & JPA實現)了。如果分配了ID,則ID將保持設置。如果沒有,那麼你將沒有身份證。

+3

安德烈是完全正確的。但我只是想用Hibernate補充說,你可以啓用一個設置'hibernate.use_identifier_rollback'(設置爲true)來重置回滾時生成的標識符的狀態。 –

+0

@SteveEbersole酷提示,但據我瞭解'如果實體被刪除'hibernate.use_identifier_rollback'被使用?我不確定回滾會發生什麼。參見:[鏈接到hibernate 3文件](http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/session-configuration.html) – Tony

1

所有託管實體都將分離。

除非您使用擴展持久性上下文,否則回滾也會結束持久性上下文。

(見OpenJPA的文檔:http://openjpa.apache.org/documentation.html

+0

好的,謝謝。但實體會發生什麼?交易前實體是否會變回狀態? – Tony

+0

我不得不測試它們,或者你可以,但是我懷疑內存中的實體會停留在回滾狀態。數據存儲中的副本當然會在交易之前返回到它們的狀態。 – WPrecht