gpt4 book ai didi

java - JPA:合并和持久化上下文

转载 作者:行者123 更新时间:2023-11-30 08:02:02 27 4
gpt4 key购买 nike

我在服务类中有以下代码:

public void updateEntity(Entity e){
EntityManager em=entityManagerFactory.createEntityManager();
em.getTransaction().begin();
em.merge(e);
em.getTransaction().commit();
em.close();
}

public Entity readEntity(int id){
EntityManager em=entityManagerFactory.createEntityManager();
Entity result=em.find(Entity.class, id);
em.close();
return result;
}

请注意,在这两个函数中,实体管理器(据我所知是持久性上下文)是关闭的。

所以当我这样做的时候:

Entity entity=service.readEntity(100);
entity.setXxx("lalala");
service.updateEntity(entity);

一切正常,我在日志中看到生成的 sql 只更改了一个字段。但是当我这样做时:

Entity entity=new Entity(100);
entity.setXxx("lalala");
service.updateEntity(entity);

更改不会写入数据库。请解释为什么。我使用 EclipseLink。

最佳答案

JPA 2.0 规范的以下摘录应该给出解释:

The merge operation allows for the propagation of state from detached entities onto persistent entities managed by the entity manager.

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.

根据规范,您的实体 应该保存到数据库中。但是因为您的更改在两种情况下都是相同的(lalala100)(find() 然后是 merge() 然后创建 merge()),您可能没有注意到数据库中的变化。我已经测试了以下情况,一切都按预期工作:

  • 我创建了一个新实体并按如下方式合并(这在数据库中创建了一个 ID = 101 的新条目):

    @Test
    public void createEmployee() {
    Employee emp = new Employee();
    emp.setName("Test");
    emp.setSalary(1000);
    tx.begin();
    em.merge(emp);
    tx.commit();
    }
  • 然后我执行了以下操作并调用了 merge(),这次只为 ID=101 的实体修改了 name 属性:

    @Test
    public void createEmployee() {
    Employee emp = new Employee();
    emp.setName("Test2");
    emp.setSalary(1000);
    emp.setId(101);
    tx.begin();
    em.merge(emp);
    tx.commit();
    }

关于java - JPA:合并和持久化上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37212878/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com