Hibernate中persist()和merge()有什么不同?
persist()
可以创建UPDATE & INSERT查询,例如:
SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
A a=new A();
session.persist(a);
a.setName("Mario");
session.flush();
在这种情况下,查询将生成如下所示:
Hibernate: insert into A (NAME, ID) values (?, ?)
Hibernate: update A set NAME=? where ID=?
因此persist()
方法可以生成、插入和更新。
现在使用merge()
SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();
这是我在数据库中看到的:
SINGER_ID SINGER_NAME
1 Ricky Martin
2 Madonna
3 Elvis Presley
4 Luciano Pavarotti
现在使用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();
这是我在数据库中看到的:
SINGER_ID SINGER_NAME
1 Ricky Martin
2 Luciano Pavarotti
3 Elvis Presley
发布于 2010-12-22 20:57:07
JPA specification包含了对这些操作的语义的非常精确的描述,比javadoc更好:
应用于实体X的持久化操作的语义如下:
cascade=PERSIST
或cascade=ALL
注释元素值注释的,或者是用等效的XML描述符元素指定的,则持久化操作将级联到X引用的实体。EntityExistsException
。对于X中的关系引用的所有实体Y,如果与Y的关系已用级联元素值cascade=PERSIST
或cascade=ALL
进行了批注,则应用于实体X的merge操作的语义如下:
IllegalArgumentException
(否则事务提交将失败)。cascade=MERGE
或cascade=ALL
对这些关系进行了批注,则合并操作将级联到这些关系引用的实体。如果X中的关系引用的所有实体Y都具有级联元素值cascade=MERGE
或cascade=ALL
,则Y将递归合并为Y‘。对于X引用的所有这样的Y,X‘被设置为引用Y’。(请注意,如果X是托管的,则X与X‘是相同的对象。)cascade=MERGE
或cascade=ALL
,则从X‘导航相同的关联将产生对具有与Y相同的持久标识的托管对象Y’的引用。发布于 2015-11-04 20:40:39
这是来自JPA
的。以一种非常简单的方式:
persist(entity)
应该与全新的实体一起使用,以将它们添加到数据库中(如果实体已经存在于数据库中,则会抛出EntityExistsException )。如果实体被分离并更改,则应使用merge(entity)
将实体放回持久性上下文。发布于 2016-07-19 16:35:44
Persist应该只在新实体上调用,而merge
则用于重新附加分离的实体。
如果您使用的是指定的生成器,那么使用merge
而不是persist
可能会导致冗余的SQL语句。
此外,为托管实体调用merge也是错误的,因为托管实体是由Hibernate自动管理的,并且在刷新持久性上下文时,脏检查机制会将它们的状态与数据库记录同步。
https://stackoverflow.com/questions/4509086
复制相似问题