JPA和Hibernate中的persist()和merge()有什么区别? [英] What is the difference between persist() and merge() in JPA and Hibernate?

查看:32
本文介绍了JPA和Hibernate中的persist()和merge()有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Hibernate 中的persist() 和merge() 有什么区别?

persist() 可以创建一个 UPDATE &插入查询,例如:

SessionFactory sef = cfg.buildSessionFactory();会话会话 = sef.openSession();A a=new A();session.persist(a);a.setName("马里奥");session.flush();

在这种情况下查询会像这样生成:

Hibernate: 插入 A (NAME, ID) 值 (?, ?)休眠:更新 A 集 NAME=?其中 ID=?

所以 persist() 方法可以生成一个插入和一个更新.

现在使用 merge():

SessionFactory sef = cfg.buildSessionFactory();会话会话 = sef.openSession();歌手歌手 = 新歌手();歌手.setName("卢西亚诺帕瓦罗蒂");session.merge(歌手);session.flush();

这是我在数据库中看到的:

SINGER_ID SINGER_NAME1 瑞奇·马丁2 麦当娜3 猫王普雷斯利4 卢西安诺·帕瓦罗蒂

现在使用 merge()

更新记录

SessionFactory sef = cfg.buildSessionFactory();会话会话 = sef.openSession();歌手歌手 = 新歌手();歌手.setId(2);歌手.setName("卢西亚诺帕瓦罗蒂");session.merge(歌手);session.flush();

这是我在数据库中看到的:

SINGER_ID SINGER_NAME1 瑞奇·马丁2 卢西安诺·帕瓦罗蒂3 猫王普雷斯利

解决方案

JPA 规范 包含对这些操作语义的非常精确的描述,比 javadoc 中的要好:

<块引用>

persist 的语义应用于实体 X 的操作是如下:

  • 如果X是一个新实体,它变得管理.实体 X 将是在或之前输入数据库事务提交或由于刷新操作.

  • 如果 X 是一个预先存在的管理实体,它是被持久操作忽略.但是,持久化操作是级联到 X 引用的实体,如果从 X 到这些的关系其他实体用cascade=PERSISTcascade=ALL注释元素值或指定使用等效的 XML 描述符元素.

  • 如果 X 是一个被移除的实体,它被管理.

  • 如果 X 是一个分离的对象EntityExistsException 可能会被抛出当调用持久操作时,或 EntityExistsException 或另一个 PersistenceException 可能是在刷新或提交时抛出.

  • 对于a 引用的所有实体 YX 的关系,如果与 Y 的关系已被注释与级联元素值cascade=PERSISTcascade=ALL,对 Y 应用持久操作.

<小时><块引用>

merge 操作的语义应用于实体 X 如下:

  • 如果 X 是一个分离的实体,状态的 X 被复制到一个预先存在的相同的受管实体实例 X'身份或 X 的新托管副本 X'已创建.

  • 如果 X 是一个新实体实例,一个新的管理实体实例 X' 被创建并且状态的 X 被复制到新的托管实体实例 X'.

  • 如果 X 是一个删除的实体实例,一个IllegalArgumentException 将是由合并操作(或事务提交将失败).

  • 如果 X是一个受管实体,它被忽略合并操作,但是,合并操作级联到关系引用的实体如果这些关系有用级联注释元素值 cascade=MERGEcascade=ALL 注释.

  • 对于所有人关系引用的实体 Y来自具有级联元素的 X值 cascade=MERGEcascade=ALL, Y递归合并为 Y'.对所有人由X引用的Y,X'被设置为参考 Y'.(注意,如果 X 是管理然后 X 是相同的对象X'.)

  • 如果 X 是合并到 X' 的实体,引用另一个实体 Y,其中 cascade=MERGEcascade=ALL 是未指定,则导航来自 X' 的相同关联产生一个对托管对象 Y' 的引用与 Y 相同的持久身份.

What is the difference between persist() and merge() in Hibernate?

persist() can create a UPDATE & INSERT query, eg:

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
A a=new A();
session.persist(a);
a.setName("Mario");
session.flush();

in this case query will be generated like this:

Hibernate: insert into A (NAME, ID) values (?, ?)
Hibernate: update A set NAME=? where ID=?

so persist() method can generate an Insert and an Update.

Now with merge():

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();

This is what I see in the database:

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Madonna
3           Elvis Presley
4           Luciano Pavarotti

Now update a record using merge()

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setId(2);
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();

This is what I see in the database:

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Luciano Pavarotti
3           Elvis Presley

解决方案

JPA specification contains a very precise description of semantics of these operations, better than in javadoc:

The semantics of the persist operation, applied to an entity X are as follows:

  • If X is a new entity, it becomes managed. The entity X will be entered into the database at or before transaction commit or as a result of the flush operation.

  • If X is a preexisting managed entity, it is ignored by the persist operation. However, the persist operation is cascaded to entities referenced by X, if the relationships from X to these other entities are annotated with the cascade=PERSIST or cascade=ALL annotation element value or specified with the equivalent XML descriptor element.

  • If X is a removed entity, it becomes managed.

  • If X is a detached object, the EntityExistsException may be thrown when the persist operation is invoked, or the EntityExistsException or another PersistenceException may be thrown at flush or commit time.

  • For all entities Y referenced by a relationship from X, if the relationship to Y has been annotated with the cascade element value cascade=PERSIST or cascade=ALL, the persist operation is applied to Y.


The semantics of the merge operation applied to an entity X are as follows:

  • If X is a detached entity, the state of X is copied onto a pre-existing managed entity instance X' of the same identity or a new managed copy X' of X is created.

  • If X is a new entity instance, a new managed entity instance X' is created and the state of X is copied into the new managed entity instance X'.

  • If X is a removed entity instance, an IllegalArgumentException will be thrown by the merge operation (or the transaction commit will fail).

  • If X is a managed entity, it is ignored by the merge operation, however, the merge operation is cascaded to entities referenced by relationships from X if these relationships have been annotated with the cascade element value cascade=MERGE or cascade=ALL annotation.

  • For all entities Y referenced by relationships from X having the cascade element value cascade=MERGE or cascade=ALL, Y is merged recursively as Y'. For all such Y referenced by X, X' is set to reference Y'. (Note that if X is managed then X is the same object as X'.)

  • If X is an entity merged to X', with a reference to another entity Y, where cascade=MERGE or cascade=ALL is not specified, then navigation of the same association from X' yields a reference to a managed object Y' with the same persistent identity as Y.

这篇关于JPA和Hibernate中的persist()和merge()有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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