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

查看:106
本文介绍了Hibernate persist()vs save()方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

hibernate文档说:
$ b

persist():




persist()使一个持久的瞬态实例。但是,它不保证标识符值将立即分配给
持久实例,分配可能发生在
时间。如果在事务边界之外调用persist(),persist()还可以保证它不会执行INSERT
语句。这是
在长时间运行的会话中有用,并且具有扩展的
会话/持久化上下文。




save() :




save()确保返回一个标识符。如果必须执行INSERT以获取标识符(例如身份生成器,而不是
序列),则无论您是交易内部还是外部的
,此INSERT都会立即发生。这在长时间运行
的会话中具有问题,因为会话/持久性
上下文。

我试着用一个小例子来说明这是如何工作的。我创建了一个名为DomesticCat的实体:

  @Entity 
public class DomesticCat {

@ Id
@GeneratedValue
私人长ID;
私人字符串名称;
}

以及一个小程序来测试它,一旦使用保存()和另一次使用 persist()

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

$ / code>

对于这个程序,hibernate为save&在这种情况下,它是:

 从双
中选择hibernate_sequence.nextval

现在我在代码中添加了一行代码:

 调用Session.flush(); 

现在hibernate为这两种情况生成插入查询,即save&坚持:

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

当我做 session.flush()时, id当我使用save()和persist()时,被分配给我的 cat 对象



最后,当我使用事务时,数据存储在数据库表中。



因此,使用这个例子我可以看到持久性和保存之间只有一个区别,那就是保存返回的标识符,在哪里持续不会。



然后文档说明了什么,有人可以帮我一些例子吗?



更新:

我使用Oracle作为数据库。 b $ b

现在我修改了我的实体类ID生成策略,如下所示递增:

  @Id 
@GeneratedValue(generator =increment)
@GenericGenerator(name =increment,strategy =increment)
私人长ID;

但即使如此,我仍可以看到 session.persist() code>正在击中数据库以获得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(flush flush id =+ cat.getId());
}

输出:

<$ Hibernate:从CAT
中选择max(id)在id = 1之后
Hibernate:插入CAT(name,id)值(?,?)
刷新后id = 1

根据hibernate的输出结果在调用session.flush()之前获取ID的DB以及session.save()也一样。因此,如果我使用Id生成策略进行增量输出,则没有区别。 解决方案

所有信息都在文档中。 save()在您拨打电话时将实体刷新到数据库。 persist()实际上只标记要在即将到来的刷新中保留的实体。与 persist 有区别,您可以更好地控制实际写入数据库的时间。


The hibernate document says:

persist():

persist() makes a transient instance persistent. However, it does not guarantee that the identifier value will be assigned to the persistent instance immediately, the assignment might happen at flush time. persist() also guarantees that it will not execute an INSERT statement if it is called outside of transaction boundaries. This is useful in long-running conversations with an extended Session/persistence context.

save():

save() does guarantee to return an identifier. If an INSERT has to be executed to get the identifier ( e.g. "identity" generator, not "sequence"), this INSERT happens immediately, no matter if you are inside or outside of a transaction. This is problematic in a long-running conversation with an extended Session/persistence context.

So I am trying with a small example on how this works. I created an entity called DomesticCat:

@Entity
public class DomesticCat {

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

and a small program to test this, once using save() and another time with persist():

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

For this program, hibernate generated same queries for save & persist, in this case it is:

select hibernate_sequence.nextval from dual

Now I added an extra line to my code saying:

session.flush();

Now hibernate generated insert query for both cases i.e save & persist:

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

Also when I do session.flush(), the id is getting assigned to my cat object when I use save() and also for persist()

Finally, when I use the transaction then the data is stored in the DB table.

So using this example I can see only single difference between persist vs save, that is save returns the identifier where as persist will not.

Then what exactly the document says, can someone please help me with some examples?

Update:

I am using Oracle as my database.

Now I modified my entity class Id generation strategy to increment as follows:

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

But even then I can see that calling session.persist() is hitting the DB to get the Id value. Here is my program and its output:

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());
}

Output:

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

As per the output hibernate is hitting the DB to get the ID before I call session.flush() and the case is same for session.save() also. So there is no difference in output if I use Id generation strategy to increment.

解决方案

All the information is in the documentation. save() flushes the entity to the database when you make the call. persist() actually just marks the entity to be persisted in the upcoming flush. There is a difference and with persist you have more control on when the actual write to the database takes place.

这篇关于Hibernate persist()vs save()方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆