java - JPA handle merge() of relationship -


i have unidirectional relation project -> projecttype:

@entity public class project extends namedentity {     @manytoone(optional = false)     @joincolumn(name = "type_id")     private projecttype type; }  @entity public class projecttype extends lookup {     @min(0)     private int progressive = 1; } 

note there's no cascade.

now, when insert new project need increment type progressive.

this i'm doing inside ejb, i'm not sure it's best approach:

public void create(project project) {     em.persist(project);      /* necessary merge type? */     projecttype type = em.merge(project.gettype());      /* necessary set type again? */     project.settype(type);      int progressive = type.getprogressive();     type.setprogressive(progressive + 1);     project.setcode(type.getprefix() + progressive); } 

i'm using eclipselink 2.6.0, i'd know if there's implementation independent best practice and/or if there behavioral differences between persistence providers, specific scenario.


update

to clarify context when entering ejb create method (it invoked jsf @managedbean):

  • project.projecttype detached
  • project new
  • no transaction (i'm using jta/cmt) active

i not asking difference between persist() , merge(), i'm asking if either

  1. if em.persist(project) automatically "reattach" project.projecttype (i suppose not)
  2. if legal call order: first em.persist(project) em.merge(projecttype) or if should inverted
  3. since em.merge(projecttype) returns different instance, if required call project.settype(managedprojecttype)

an explaination of "why" works in way , not in welcome.

you need merge(...) make transient entity managed entity manager. depending on implementation of jpa (not sure eclipselink) returned instance of merge call might different copy of original object.

myentity unmanaged = new myentity(); myentity managed = entitymanager.merge(unmanaged); assert(entitymanager.contains(managed));  // true if worked out assert(managed != unmanaged);  // true, depending on jpa impl. 

if call manage(entity) entity managed, nothing happen.

calling persist(entity) make entity managed, returns no copy. instead merges original object , might call id generator (e.g. sequence), not case when using merge.

see this answer more details on difference between persist , merge.

here's proposal:

public void create(project project) {     projecttype type = project.gettype(); // maybe check if null     if (!entitymanager.contains(type)) {  // type transient         type = entitymanager.merge(type); // or load type         project.settype(type); // update reference     }      int progressive = type.getprogressive();     type.setprogressive(progressive + 1); // mark dirty, update on flush      // set "code" before persisting "project" ...     project.setcode(type.getprefix() + progressive);     entitymanager.persist(project);      // ... no additional update required after     // insert on "project". } 

update

if em.persist(project) automatically "reattach" project.projecttype (i suppose not)

no. you'll exception (hibernate anyway) stating, you're trying merge transient reference.

correction: tested hibernate , got no exception. project created unmanaged project type (which managed , detached before persisting project). but project type's progression not incremented, expected, since wasn't managed. yeah, manage before persisting project.

if legal call order: first em.persist(project) em.merge(projecttype) or if should inverted

it's best practise so. when both statements executed within same batch (before entity manager gets flushed) may work (merging type after persisting project). in test worked anyway. said, it's better merge entities before persisting new ones.

since em.merge(projecttype) returns different instance, if required call project.settype(managedprojecttype)

yes. see example above. persistence provider may return same reference, isn't required to. sure, call project.settype(mergedtype).


Comments

Popular posts from this blog

Magento/PHP - Get phones on all members in a customer group -

php - .htaccess mod_rewrite for dynamic url which has domain names -

Website Login Issue developed in magento -