0

考虑以下pojo:

@Embeddable
public class Info {
  private String name;
  public String getName(){
    return name;
  }
  public void setName(String name){
    this.name=name;
  }
}

@Entity
public class Person {
  @Id
  private long pid;
  public Person(long pid){
    this.pid=pid;
  }

  @Embedded
  private Info info = new Info();
  public Info getInfo(){
    return info;
  }
}

和一些访问它的代码

{

 Person p = new Person(1);
 p.getInfo().setName("Foo");

 EntityManager em = ...

 em.merge(p); // <-- SQL INSERT or UPDATE expected

}

执行以下 SQL:

第一次运行 merge() 执行以下操作(如预期的那样):

  • SELECT p.name FROM person p where p.pid=1
  • 插入人(pid,name)值(1,'Foo')

第二次运行 merge() 执行以下操作,这是出乎意料的:

  • SELECT p.name FROM person p where p.pid=1
  • 更新人员 SET name='Foo' WHERE pid=1

为什么更新发生在第二次运行?即使“Foo”仍然等于“Foo”?!

如果我不使用 Info Embeddable,而是将“name”属性放入 Person 类,则第二次运行的 merge() 会像预期的那样工作:有一个 SELECT 但没有执行 UPDATE

4

1 回答 1

0

对我来说,这似乎是一个 OpenJPA 错误或缺少的功能,如果我切换到 EclipseLink 实现,一切都会按预期工作。

此外,在现有 ID(但在分离实体上)的 .merge(new Entity()) 期间,所有具有不同值的字段都使用 EclipseLink 更新(也无效),而在 OpenJPA 中,空字段不会同步到数据库。因此,EclipseLink 再次按预期执行。

于 2015-01-08T13:29:49.990 回答