java - Why is this JPA 2.0 entity merged only after a find()? -
my application creates object in first transaction. then, transaction tries update database changes, instead of updating entity, new 1 created. if find
before merge
, right record updated. why that?
this entity:
@entity public class myobject implements serializable{ @id @generatedvalue(strategy = generationtype.sequence, generator = "my_seq") @sequencegenerator(name = "my_seq", sequencename = "my_seq_gen", allocationsize = 1) long id; string stuff; string businesskey; // getter, setters, hashcode, equals (using "businesskey") }
this record created , updated: (see below create
, update
):
myobject obj = bean.create(); bean.update(obj);
but said before, fails update first record, creates 1 instead!
if try find
entity before merge operation (without doing returned object), it's correctly updated (see below create
, findandupdate
):
myobject obj = bean.create(); bean.findandupdate(obj);
here ejb:
@transactionattribute(transactionattributetype.requires_new) @stateless public class bean { final static logger logger = loggerfactory.getlogger(bean.class); @persistencecontext(unitname = "myunit") entitymanager em; public myobject create(){ myobject obj = new myobject(); obj.businesskey = "some string"; em.persist(obj); logger.debug("myobject.id: {}", obj.id); // eg. 100 return obj; } public void update(myobject obj){ obj.stuff = "some stuff"; myobject merged = em.merge(obj); logger.debug("obj.id: {}", obj.id); // still 100 logger.debug("merged.id: {}", merged.id); // new id: 101! } public void findandupdate(myobject obj){ obj.stuff = "some stuff"; em.find(myobject.class, obj.id); // doing nothing returned myobject myobject merged = em.merge(obj); logger.debug("obj.id: {}", obj.id); // still 100 logger.debug("merged.id: {}", merged.id); // still 100! } }
the problem seems outside given code. guessing myobject instance passing on update() created either calling new
or through sort of deserialization, json example. entity manager instance em
(usually created @ request start , destroyed after it's end) contains entities have been loaded it. these entities compared reference when looked-up , not tested key equality. in essence, using contains
, asking "are tracking instance of object?", , can have many instances of object of same class same primary key, entity manager not track them unless received reference it.
Comments
Post a Comment