Search code examples
openjpaembeddable

JPA / OpenJPA merge always causes SQL UPDATE on Embedded objects


consider following pojos:

@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;
  }
}

and some code accessing it

{

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

 EntityManager em = ...

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

}

following SQLs are executed:

the 1st run merge() does following (as expected):

  • SELECT p.name FROM person p where p.pid=1
  • INSERT INTO person (pid,name) VALUES (1,'Foo')

the 2nd run merge() does following, which is unexpected:

  • SELECT p.name FROM person p where p.pid=1
  • UPDATE person SET name='Foo' WHERE pid=1

WHY does the UPDATE happen in 2nd run? even though "Foo" still equals to "Foo"?!

If I don't use the Info Embeddable, instead place the "name" property into Person class, the 2nd run of merge() works like expected: there is a SELECT but no UPDATE executed


Solution

  • it seems like an OpenJPA bug or a missing feature to me, if I switch to EclipseLink implementation, everything works as expected.

    Additionally, during a .merge( new Entity() ) on existent ID (but on detached entity) all fields with different values are updated (also nullified) using EclipseLink whereas in OpenJPA the null fields are not synced to database. So again, EclipseLink performs here as expected.