Search code examples
jpaopenjpa

JPA save behavior


I need help understanding how the EntityManager.merge() works with regard to an existing entity. This is with openJPA if it matters.

Here is my current understanding:

  1. Any time a new Java object is created at least one of the constructors of that object are executed.
  2. merge() returns a new instance of the object being saved

Observed behavior via a debugger is that merge() does not call the constructor for the new instance.

An explanation, link or book reference would be greatly appreciated that can help me understand these questions:

  1. How can objects be created without invoking at least one of the constructors defined for that class?
  2. Given that merge() never calls the constructor, what is the best practice for calling constructor code be called during a merge?

Thanks for taking the time to think about my questions!


Solution

  • According to JPA spec:

    The entity class must have a no-arg constructor. The entity class may have other constructors as well. The no-arg constructor must be public or protected.

    So no matter how many constructors you have defined in your entity, the only constructor that will be invoked is the no-arg constructor (constructor without arguments/parameters). Your JPA provider may not instantiate your entity via the new operator, it does this dynamically thru reflection using the Class.newInstance method. See sample below:

    Class clazz = Class.forName("com.test.TestEntity");
    clazz.newInstance();
    

    On your question about merge: A merge operation does not guarantee a new entity object to be instantiated. If the entity is already managed and already existing in the persistence context, it won't have to create a new object, it will just update the one already existing in the persistence context.

    If you want to execute some code/logic before any entity gets persisted or updated, might as well consider using lifecycle callback methods using @PrePersist, @PreUpdate annotations.