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

标签 java hibernate jpa orm entity

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

最佳答案

JPA specification包含对这些操作语义的非常精确的描述,比在 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.

关于java - JPA 和 Hibernate 中的 persist() 和 merge() 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4509086/

相关文章:

java - 将堆栈大小设置为线程似乎在android中没有什么区别

java - Modbus 驱动程序 : C vs Java

javax.el.E​​LException : java. lang.NoClassDefFoundError: org/hibernate/HibernateException

java - 带两个参数的 Hibernate IN 查询

java - 不在 Hibernate 中使用 EntityManager 的后果

java - Executors.newFixedThreadPool 中 LinkedBlockingQueue 的好处

java - Hibernate Criteria Left 连接两个表

java - 具有限制和偏移量的 JPQL 查询注释

java - 循环是否每次都需要更长的时间来执行?

java - JAXB键值问题