Different behavior with persist() and queried instances?

#1

Hi,

We have a simple class that by itself contains (among others) a property pointing to a collection:

class Bla
{
    @OneToMany(cascade = CascadeType.ALL)
    private List<AttributeEntity> metaAttributes = new ArrayList<AttributeEntity>();
}

Now we do a simple em.persist(BlaInstance) and afterwards modify the metaAttributes property within a transaction, however this is not reflected in the db. Reason is simply that the metaAttributes property is still a regular ArrayList instance and no special proxy class from objectdb which can track changes. However, when we do simple re-select the object instance after inserting it into the database everything is perfect -- in debugger we can see that the metaAttributes points to a proxy class now.

Anyway, long text short question --> are we really supposed to *always* re-select *every* object after doing a persist() to get proper behavior? shouldn't an object instance persisted the first time with persist() behave *exactly* as if we'd have re-selected it from the database? In each other case, the automatic change tracking is driven to be being pretty useless..

thanks,

Alex

#2

I am getting closer.. looks like persist works though in a sample project, *after* the commit, my list property is correctly enhanced with odb specific fields, however in my other project doing exactly the same (except not using the java agent enhancer but maven compile time enhancer but the class itself is enhanced as I can see the odbtracker field) it doesn't work.

Alex

#3

Okay I think I know what's going:

After the commit and persist calls I do close the entity manager so my object gets detached. Between the persist() and the commit() call, my list property seems to be correctly tracked as it includes the odb specific fields (it is an objectdb.java.util.ArrayList). However, after detaching it becomes a regular java.util.Array again which of course doesn't mark the object dirty when getting changed so a following merge call doesn't bring any success either. How is this supposed to work?

Alex

#4

Looks like calling merge() *before* modifying the underlying list property does the job oh well.. as such I might need to modify my interfaces accordingly.

Alex

#5

okay I am giving up after a whole day struggling.. The one thing I can *definitely* say is this:

- Create a class with a simple list in it like in my first post
- Open up connection to server to any database using entity manager factory
- Create instance of an entity manager using the entity manager factory
- Create instance of your class, call persist, commit the transaction

  -> OK, object is saved in db and the list of the object is marked as empty

- Now close the entity manager and create a new one using the same factory.
- Start transaction again, call merge with your existing instance of the new entity manager instance
- Try to modify (add new item) the list of your instance
- Commit the transaction

  -> FAIL, the list of the object is still set to empty in db eventhough it is filled

Btw the list's type in debugger correctly points to objectdb.java.util.ArrayList after the merge call but yet..

Please help!!!

Alex

#6

Oh great.. just figured that even JDOHelper.makeDirty(object, "listPropertyName"); doesn't change it, the list is still empty in db after commit!!

please help, I cannot even go further with this issue..

thanks!

Alex

#7

Thank you for your bug report.

Please try build 2.2.3_04 that should fix merging collections.

ObjectDB Support

Reply