[英]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.