Java Hibernate persist()vs save()方法

Java Hibernate persist()vs save()方法,java,hibernate,Java,Hibernate,报告说: persist(): persist()使临时实例持久化。但是,它不能保证将标识符值分配给 如果是持久实例,则分配可能会在刷新时发生 时间persist()还保证它不会执行插入 语句(如果在事务边界之外调用)。这是 在与扩展用户的长时间对话中非常有用 会话/持久性上下文 save(): save()不保证返回标识符。如果必须执行插入以获取标识符(例如“标识”生成器,而不是 “序列”),无论您是否 在交易的内部或外部。这在某种程度上是有问题的 具有扩展会话/持久性的长时间运行对话 上下文

报告说:

persist(): persist()使临时实例持久化。但是,它不能保证将标识符值分配给 如果是持久实例,则分配可能会在刷新时发生 时间persist()还保证它不会执行插入 语句(如果在事务边界之外调用)。这是 在与扩展用户的长时间对话中非常有用 会话/持久性上下文

save(): save()不保证返回标识符。如果必须执行插入以获取标识符(例如“标识”生成器,而不是 “序列”),无论您是否 在交易的内部或外部。这在某种程度上是有问题的 具有扩展会话/持久性的长时间运行对话 上下文

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

@Entity
public class DomesticCat {

    @Id
    @GeneratedValue
    private long id;
    private String name;
}
还有一个小程序来测试这一点,一次使用
save()
,另一次使用
persist()

对于该程序,hibernate为保存和持久化生成了相同的查询,在本例中为:

select hibernate_sequence.nextval from dual
现在,我在我的代码中添加了一行额外的代码:

session.flush();
现在hibernate为这两种情况生成了插入查询,即保存和持久化:

insert into CAT (name, id) values (?, ?)
另外,当我执行
session.flush()
时,当我使用save()和persist()时,
id
被分配给我的
cat
对象

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

因此,使用这个示例,我可以看到persist和save之间只有一个区别,即save返回标识符,而as persist不会返回标识符

那么文件到底说了什么,有人能帮我举一些例子吗

更新:

我正在使用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()之前,hibernate正在点击数据库获取ID,session.save()的情况也一样。所以,如果我使用Id生成策略来增加,输出没有区别。

这是一个简单的逻辑问题

它不能保证标识符值将立即分配给持久实例

这和

它保证不会立即将标识符值分配给持久实例


数据库使用的ID生成策略是使用序列。在这种情况下,Hibernate在调用persist()时向序列询问下一个ID。如果数据库的ID生成策略是使用自动增量列,则仅当实体在刷新时插入数据库时,才会将ID分配给实体。

所有信息都在文档中
save()
在调用时将实体刷新到数据库中
persist()
实际上只是在即将到来的刷新中标记要持久化的实体。这是有区别的,使用
persist
可以更好地控制对数据库的实际写入时间。

关键在于
这在长时间运行的对话中非常有用,其中
persist
save
更可取(插入许多对象)。感谢您的回答。现在,我将Id生成策略设置为增量,并且使用save和persist没有任何区别。我已经更新了我的问题,详细说明了我的尝试。你能检查一下吗?这不是我的意思。我的意思是在数据库中使用自动递增列。Oracle没有这个功能。比如说MySQL,谢谢heikkim,你能给我一个小例子,让我看看两者的区别吗。
before id=0
Hibernate: select max(id) from CAT
after id=1
Hibernate: insert into CAT (name, id) values(?, ?)
after flush id=1