0

有人可以解释这种行为吗?

给定下面的实体MyEntity,下面的代码

EntityManagerFactory emf = Persistence.createEntityManagerFactory("greetingPU");
EntityManager em = emf.createEntityManager();

MyEntity e = new MyEntity(); 
e.setMessage1("hello"); e.setMessage2("world");
em.getTransaction().begin();
em.persist(e);
System.out.println("-- Before commit --");
em.getTransaction().commit();
System.out.println("-- After commit --");

导致输出指示 EclipseLinks EntityManager 或其关联对 MyEntity 的“setter”方法的多次调用。这种行为是可以预期的吗?可能是出于某些内部性能或结构原因?其他 JPA 实现是否显示相同的行为?

-- Before commit --
setId
setId
setMessage1
setMessage2
setId
setMessage1
setMessage2
-- After commit --

似乎有两种不同的重新分配。首先,一组初始的 Id。第二,整个Entity的两个连续设置。调试显示给定“setter”的所有调用都具有与参数相同的对象。

@Entity
public class MyEntity {

  private Long id;
  private String message1;
  private String message2;

  @Id
  @GeneratedValue(strategy=GenerationType.SEQUENCE)
  public Long getId(){ return id; }
  public void setId(Long i) { 
    System.out.println("setId");
    id = i;
  }

  public String getMessage1() { return message1; }
  public void setMessage1(String m) {
    message1 = m;
    System.out.println("setMessage1");
  }

  public String getMessage2() { return message2; }
  public void setMessage2(String m) {
    message2 = m;
    System.out.println("setMessage2");
  }
}
4

1 回答 1

1

你用编织吗?http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving

EclipseLink 必须调用一次 setId 才能在托管实体实例中设置生成的 ID。它还将创建一个实例并为共享缓存设置其值,解释另一个 setId 和 set values 调用。如果您不使用编织,因为 EntityManager 仍然存在,EclipseLink 还将创建一个备份实例以用于比较未来的更改 - 事务提交后对托管实体的任何更改仍需要跟踪。

如果这不是可取的,编织允许使用属性更改跟踪,这样就不需要备份副本来跟踪更改。您也可以关闭共享缓存,但除非您遇到性能或过时数据问题,否则不建议这样做。

于 2013-07-02T13:10:03.457 回答