在Hibernate中,save()
和saveOrUpdate()
都是用于持久化對象的方法,但它們的適用場景和行為有顯著差異:
1. save()
方法
-
核心行為:
- 僅適用于瞬時態(Transient)對象(即新創建、未與Session關聯的對象)。
- 會立即為對象分配一個標識符(ID),并計劃在事務提交時執行INSERT操作。
- 若嘗試對已持久化(Persistent)或游離態(Detached)對象調用
save()
,會拋出異常。
-
返回值:
返回生成的Serializable
類型的主鍵ID。 -
典型場景:
User user = new User(); // 瞬時態對象 Serializable id = session.save(user); // 執行INSERT,返回ID
2. saveOrUpdate()
方法
-
核心行為:
- 智能判斷對象狀態:
- 若對象為瞬時態:執行INSERT操作(類似
save()
)。 - 若對象為游離態:執行UPDATE操作(更新數據庫記錄)。
- 若對象已為持久態:忽略操作(無需重復保存)。
- 若對象為瞬時態:執行INSERT操作(類似
- 不會返回主鍵ID(無返回值,
void
)。
- 智能判斷對象狀態:
-
典型場景:
User user1 = new User(); // 瞬時態 session.saveOrUpdate(user1); // 執行INSERTUser user2 = session.get(User.class, 1L); // 持久態 session.evict(user2); // 轉為游離態 user2.setName("NewName"); session.saveOrUpdate(user2); // 執行UPDATE
3. 關鍵區別總結
特性 | save() | saveOrUpdate() |
---|---|---|
適用對象狀態 | 僅瞬時態 | 瞬時態、游離態 |
返回值 | 返回主鍵ID | 無返回值(void) |
重復調用 | 對同一對象重復調用會引發異常 | 對同一對象可安全重復調用 |
數據庫操作 | 總是INSERT | 可能INSERT或UPDATE |
4. 如何選擇?
-
使用
save()
:
明確需要插入新記錄且無需處理游離態對象時(如嚴格的新增操作)。 -
使用
saveOrUpdate()
:
不確定對象狀態(如從表單接收的數據可能對應新增或修改),或需要統一處理插入/更新邏輯時。
?? 注意:
- 對游離態對象調用
save()
會拋出TransientObjectException
。saveOrUpdate()
可能因版本沖突(如樂觀鎖)拋出StaleObjectStateException
。