首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >_方法_()方法。

_方法_()方法。
EN

Stack Overflow用户
提问于 2014-09-16 07:04:10
回答 2查看 2.1K关注 0票数 1

hibernate文档说:

坚持():

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

保存():

save()确实保证返回标识符。如果必须执行INSERT才能获得标识符(例如,“标识”生成器,而不是“序列”),则无论您是在事务的内部还是外部,插入都会立即发生。这在具有扩展会话/持久性上下文的长时间会话中是有问题的。

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

代码语言:javascript
复制
@Entity
public class DomesticCat {

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

和一个小程序来测试这一点,一次使用save(),另一次使用persist()

代码语言:javascript
复制
private static void saveData() {
    Session session = getSession();
    DomesticCat cat = new DomesticCat();
    cat.setName("My Cat");
    //session.save(cat);
    session.persist(cat);
}

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

代码语言:javascript
复制
select hibernate_sequence.nextval from dual

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

代码语言:javascript
复制
session.flush();

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

代码语言:javascript
复制
insert into CAT (name, id) values (?, ?)

同样,当我使用session.flush()时,id也会被分配给我的cat对象,当我使用cat()时,也是为了持久化()

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

因此,使用此示例,我只能看到持久化与保存之间的单一区别,即保存返回标识符,因为持久化不会。

那么这份文件到底是怎么说的,有人能帮我举几个例子吗?

更新:

我使用Oracle作为我的数据库。

现在,我将实体类Id生成策略修改为增量,如下所示:

代码语言:javascript
复制
@Id
@GeneratedValue(generator="increment")
@GenericGenerator(name="increment", strategy = "increment") 
private long id;

但即使如此,我仍然可以看到调用session.persist()是为了获取Id值而命中DB。这是我的程序及其输出:

代码语言:javascript
复制
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());
}

输出:

代码语言:javascript
复制
before id=0
Hibernate: select max(id) from CAT
after id=1
Hibernate: insert into CAT (name, id) values(?, ?)
after flush id=1

根据输出,hibernate在调用session.flush()之前访问DB以获取ID,session.save()的情况也是一样的。因此,如果使用Id生成策略进行增量,则输出没有差别。

EN

回答 2

Stack Overflow用户

发布于 2014-09-16 07:10:12

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

票数 2
EN

Stack Overflow用户

发布于 2014-09-16 07:09:00

这是一个简单的逻辑问题。

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

不是一回事

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

数据库使用的ID生成策略是使用序列。在这种情况下,Hibernate在调用持久性()时询问下一个ID的序列。如果数据库的ID生成策略是使用自动增量列,则只有当实体在同花顺时插入到数据库时,ID才会分配给实体。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25862537

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档