Issue #2479: Enhancing a class causes it to not save changes.

Type: Bug ReoprtVersion: 2.8.1Priority: NormalStatus: ClosedReplies: 6
#1

So when we enhance the Account class, no changes are saved to it. When it is reflection mode, everything works perfectly.

In reflection mode, the objectdb log on debug mode refers to classes that have not existed for ages.  In enhancement mode, there are no exceptions. I can't figure out how ObjectDB is holding on to the old classes, as they have not existed for  months.  I've tried running the database through DBDoctor, and it didn't help.

I've include the java files of by models, the objectdb logs for both the enhanced and unenhanced versions, and the objectdb.conf.

-------------Update-------------

The problem appears to be reflective setting of fields.  In the unit test I uploaded, if you reflectively set the label, it fails to save when enhanced and passes otherwise (see DBTest.java for details).

Is there a set of rules somewhere that says what the unsafe operations are for enhanced classes?          

        Thanks,

                 Emily

#2

In enhancement mode ObjectDB tracks changes to entity objects when the values of their persistent fields are modified directly, but cannot do that when the values are changed by reflection.

In reflection mode ObjectDB doesn't track anything until flush/commit and then it just compares the content of the object at the beginning of the transaction to the current content of the object. This is much less efficient but can work well also with updating objects with reflection.

If you want to use enhanced classes and modify objects using reflection you can let ObjectDB know when an object is modified and needs to be saved to the database by invoking:

    JDOHelper.makeDirty(obj, null);

It is a JDO method but will work regardless if you use JPA or JDO.

ObjectDB Support
#3

You rock! That's exactly what I needed. Thanks a million :-) :-) :-) :-)

So, I was wondering if you had equally magical and completely on-point advise on how to figure out why ObjectDb is holding onto classes that no longer exist?  You can see the classes in the obj-reflection.log. As far as I can tell, it's not causing any problems,   so feel free to tell me to take a hike, but I hate having unexplained exceptions in logs as they tend to bite you in the long term...


[2019-09-30 17:19:13 #1 type.loader] 
java.lang.ClassNotFoundException: models.Strack$Status
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

#4

Unfortunately,   I spoke too soon, as while  you completely solved by problem for the reflective fields, I'm still seeing it now in, as far as I can tell, random places when I am not using reflection. 

The following test body works when I have enhancement off, and fails otherwise.  (Included updated DBTest.java) Any idea what might be going wrong? 

        DB.startTransaction();
        Account test = accounts.get("test");
        test.positions = UPDATED_EXAMPLE_LABEL;
        test = refresh(accounts, test.id);
        assertEquals(test.positions, UPDATED_EXAMPLE_LABEL); So, I w

#5

Without looking at your test case, one important thing to remember when using enhancement is that all the classes must be enhanced, or at least all the entity classes and all the classes that contain code that access or modify persistent fields in the entity classes directly (if the persistent fields are defined as private than they are only accessed and modified directly from entity classes, but all the entity classes have to be enhanced).

Regarding the new question in #3 above, please create a new thread, as it seems to be unrelated to the subject of this thread.

ObjectDB Support
#6

That makes sense. How do I tell the agent to apply itself to the test and control classes?  As they are being compiled at the same time as the model classes...

#7

It depends on your specific configuration.

Hopefully one of the supported enhancement paths can match your needs.

If you define all your persistent fields as private and access them using property methods it may make things easier as in that case only entity classes will require enhancement.

ObjectDB Support

Reply