繁体   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