JPA和Hibernate中的persist()和merge()有什么区别? [英] What is the difference between persist() and merge() in JPA and Hibernate?
问题描述
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=PERSIST
或cascade=ALL
注释元素值或指定使用等效的 XML 描述符元素.如果 X 是一个被移除的实体,它被管理.
如果 X 是一个分离的对象
EntityExistsException
可能会被抛出当调用持久操作时,或EntityExistsException
或另一个PersistenceException
可能是在刷新或提交时抛出.对于a 引用的所有实体 YX 的关系,如果与 Y 的关系已被注释与级联元素值
cascade=PERSIST
或cascade=ALL
,对 Y 应用持久操作.
<小时><块引用>
merge 操作的语义应用于实体 X 如下:
如果 X 是一个分离的实体,状态的 X 被复制到一个预先存在的相同的受管实体实例 X'身份或 X 的新托管副本 X'已创建.
如果 X 是一个新实体实例,一个新的管理实体实例 X' 被创建并且状态的 X 被复制到新的托管实体实例 X'.
如果 X 是一个删除的实体实例,一个
IllegalArgumentException
将是由合并操作(或事务提交将失败).如果 X是一个受管实体,它被忽略合并操作,但是,合并操作级联到关系引用的实体如果这些关系有用级联注释元素值
cascade=MERGE
或cascade=ALL
注释.对于所有人关系引用的实体 Y来自具有级联元素的 X值
cascade=MERGE
或cascade=ALL
, Y递归合并为 Y'.对所有人由X引用的Y,X'被设置为参考 Y'.(注意,如果 X 是管理然后 X 是相同的对象X'.)如果 X 是合并到 X' 的实体,引用另一个实体 Y,其中
cascade=MERGE
或cascade=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
orcascade=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 theEntityExistsException
or anotherPersistenceException
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
orcascade=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
orcascade=ALL
annotation.For all entities Y referenced by relationships from X having the cascade element value
cascade=MERGE
orcascade=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
orcascade=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屋!