簡體   English   中英

Hibernatepersist()vs save()方法

[英]Hibernate persist() vs save() method

休眠文件說:

堅持():

persist()使瞬態實例持久化。 但是,它不能保證將標識符值立即分配給持久實例,分配可能在刷新時發生。 persist()還保證如果在事務邊界之外調用它,則不會執行INSERT語句。 這在具有擴展會話/持久性上下文的長時間對話中很有用。

救():

save()保證返回標識符。 如果必須執行INSERT來獲取標識符(例如,“身份”生成器,而不是“序列”),則無論您是在事務內部還是外部,此INSERT都會立即發生。 在具有擴展的會話/持久性上下文的長時間對話中,這是有問題的。

因此,我正在嘗試一個有關其工作原理的小例子。 我創建了一個名為DomesticCat的實體:

@Entity
public class DomesticCat {

    @Id
    @GeneratedValue
    private long id;
    private String name;
}

以及一個小程序對此進行測試,一次使用save() ,另一次使用persist()

private static void saveData() {
    Session session = getSession();
    DomesticCat cat = new DomesticCat();
    cat.setName("My Cat");
    //session.save(cat);
    session.persist(cat);
}

對於此程序,hibernate生成了相同的保存和持久化查詢,在這種情況下為:

select hibernate_sequence.nextval from dual

現在,我在代碼中增加了一行:

session.flush();

現在,休眠生成兩種情況下的插入查詢,即保存並持續:

insert into CAT (name, id) values (?, ?)

同樣當我執行session.flush() ,當我使用save()以及persist()時,也將id分配給我的cat對象

最后,當我使用事務時,數據將存儲在DB表中。

因此,使用此示例,我只能看到持久性與保存之間的唯一區別,即保存返回標識符,而持久性則不會。

那么,文件確切說明了什么,有人可以幫我提供一些例子嗎?

更新:

我正在使用Oracle作為數據庫。

現在,我將實體類ID生成策略修改為如下遞增:

@Id
@GeneratedValue(generator="increment")
@GenericGenerator(name="increment", strategy = "increment") 
private long id;

但是即使那樣,我仍然可以看到調用session.persist()正在擊中數據庫以獲取Id值。 這是我的程序及其輸出:

private static void saveData() {
    Session session = getSession();
    DomesticCat cat = new DomesticCat();
    cat.setName("My Cat");
    System.out.println("before id="+cat.getId());
    session.persist(cat);
    System.out.println("after id="+cat.getId());
    session.flush();
    System.out.println("after flush id="+cat.getId());
}

輸出:

before id=0
Hibernate: select max(id) from CAT
after id=1
Hibernate: insert into CAT (name, id) values(?, ?)
after flush id=1

根據輸出,休眠狀態是在我調用session.flush()之前命中數據庫以獲取ID,session.save()的情況也相同。 因此,如果我使用ID生成策略遞增,則輸出不會有差異。

這是一個簡單的邏輯問題。

它不能保證將標識符值立即分配給持久實例

和...不一樣

它保證不會立即將標識符值分配給持久實例

用於數據庫的ID生成策略是使用序列。 在這種情況下,Hibernate在調用persist()時向序列詢問下一個ID。 如果數據庫的ID生成策略是使用自動增量列,則僅在刷新時將實體插入數據庫時​​,才將ID分配給實體。

所有信息都在文檔中。 調用時, save()將實體刷新到數據庫。 persist()實際上只是將實體persist()在即將到來的刷新中。 這是有區別的,並且通過persist您可以更好地控制何時實際寫入數據庫。

暫無
暫無

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

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