java - Hibernate persist() 与 save() 方法

标签 java hibernate

hibernate document说:

坚持():

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() 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.

所以我尝试用一​​个小例子来说明它是如何工作的。我创建了一个名为 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();

现在 hibernate 为两种情况生成插入查询,即保存和持久:

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

此外,当我执行 session.flush() 时,当我使用 save() 时,id 会被分配给我的 cat 对象,并且也适用于 persist()

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

因此,使用这个示例,我可以看到 persist 与 save 之间只有一个区别,即 save 返回标识符,而 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生成策略来递增,输出没有差异。

最佳答案

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

关于java - Hibernate persist() 与 save() 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25862537/

相关文章:

java - Spring 启动: MockMvc returning strange responses

java - 原子变量与同步方法

java - Estado HTTP 500-请求处理失败;嵌套的异常是org.hibernate.HibernateException:当前 session 找不到 session

java - Hibernate - 使用包含父 ID 的复合键 - OneToMany

java - 按 ID 跨表拆分 hibernate 实体

java - 使用 Hibernate Envers 获取两个修订版之间的旧值和新值

java - 从 android studio 中的图库获取图像 - 不相关的代码

java - 如何使用 Jsoup 选择元素

java - org.springframework.orm.hibernate4.annotation.AnnotationSessionFactoryBean

java - 找不到类型 : java. lang.Long 的 validator 。带帖子ID