objectdb-2.6.9_02 (with "objectdb.temp.no-enhancement-crc-check") vs. generic classes with interfaces: detailed investigation

#1

objectdb-2.6.9_02 (with "objectdb.temp.no-enhancement-crc-check" system property)

The following is a detailed report on investigation of multiple issues that have been mentioned in the following forum postings and issue reports (but please do not visit them from here now, the diagnostics there are now obsolete):

Issue #1924 - ObjectDB-2.6.9: Failed to commit transaction: Failed to set numeric value of field property Element.id using reflection

Possible cause for "Enhancement of type ... is old and cannot be used"

This report concerns investigation of issues when using with generic classes for "deep" value wrappers with signatures like:

@Entity abstract public class Value<T> extends [SomeOtherEntity] implements IValue<T> {

@Entity public class BooleanValue extends Value<Boolean> implements IBooleanValue {

@Entity public class IntegerValue extends Value<Integer> ... {

@Entity abstract public class Quantity<T extends Number> extends Value<T> implements IQuantity<T> {

@Entity public class FloatQuantity extends Quantity<Float> implements IFloatQuantity {

@Entity public class IntegerQuantity extends Quantity<Integer> implements IIntegerQuantity {

@Entity public class StringValue extends Value<String> implements IStringValue {

@Entity public class EnumValue<T extends Enum<T>> extends Value<T> {

It is important to note that Value<T> implements IValue<T>, as this has consequences for at least one issue (see below).

The above "deep" value wrapper classes are crucial to an Expert System web app I develop; please do not be further concerned with why one would bother to wrap something like a Boolean in this fashion, it is however a very powerful and crucial technique (and it is not used in all cases for every trivial boolean value in the system, just for Expert System cases).

To make things simpler, this posting will examine only these 2 cases:

@Entity public class BooleanValue extends Value<Boolean> implements IBooleanValue {

@Entity public class EnumValue<T extends Enum<T>> extends Value<T> {

Note in particular the complex signature of the EnumValue compared with the other generic value wrapper examples, as it exhibits a problem with ObjectDB that the others do not.

 

Some important remarks about the analysis, diagnostics, and the testing setup:

- The diagnostics here have been recorded carefully at every step, including Git tracking and tracking in a CMS web system.

- I have used both a console test app and a NetBeans web app in Glassfish; the initial report is limited to the console app, as the web app introduces some other factors (especially concerning the Ant build).

- The NetBeans project for the console app uses a post-compile, pre-deployment Ant script invoked using Clean and Build that enhances every entity class in the system.

- Very important: I discovered to my horror (using Java decompilers and .class file time stamp checks) that when running my "console" test app in NetBeans IDE using the Run context menu it was in fact over-writing the enhanced .class files ! Therefore, some of my diagnostics in other recent postings are incorrect. This must be something to do with the Ant build.xml and build-impl.xml (a problem for another day).

- All reports here are from executing the console test app from a shell/terminal window, NOT from NetBeans (although the test app is developed in NetBeans and the Clean and Build with enhancement works fine).

- I have used Java decompilers to check the ObjectDB enhancement carefully. I recommend the JD-GUI decompiler, which has better support for generics than the now-obsolete JAD. You can also find out about other Java decompilers (including a cloud-based service - http://www.javadecompilers.com/). If you are new to ObjectDB I highly recommend that you inspect the decompiled enhanced output for entity classes.

- I have also used UNIX file timestamp checking to ensure enhancement from Clean and Build has not been corrupted.

- No javaagent enhancement is used at any stage (and timestamp checking of enhanced .class files indicates that no "automatic" enhancement has taken place).

- [EDIT: contrary to my original report, to prevent the persistence error one can explicitly set System.setProperty("objectdb.temp.no-enhancement-crc-check", "true"); in objectdb-2.6.9_02 because the default behaviour is "false"]

About Build 2.6.9_02 and the "objectdb.temp.no-enhancement-crc-check" system property 

From ObjectDB support from 2016-08-19:

'Using generic entity classes with ObjectDB may work to some extent. You can use a generics class parameter as the type of a persistent field, but in that case ObjectDB will consider that persistent field type as java.lang.Object.

Build 2.6.9_02 supports an option to disable the "Enhancement ... is old" check and error:

    System.setProperty("objectdb.temp.no-enhancement-crc-check", "true");

Set the property before accessing ObjectDB do disable ObjectDB checks. If all your classes are enhanced properly and the problem is in this check then you may be able to use your application with the last build.'

What my test app does:

- Creates a Project entity with a Model entity child which in turn has BooleanValue and EnumValue entity children.

- Uses Java Reflection to inspect all getters and setters (I am using property-based JPA) and all ObjectDB hidden methods (which are no longer getters/setters) and echos this information. This is also one way of checking the enhancement.

- Attempts to persist the Project (which under some circumstances gives errors).

This forum posting does NOT report on anything other than errors during persistence, that is no conclusions are drawn yet about whether ObjectDB can handle retrieval of information in such generic value wrapper classes.

 

Case1: 

- System.setProperty("objectdb.temp.no-enhancement-crc-check", "false");

- EnumValue has the following methods that are NOT defined as operations in IValue<T>.

    private T oldValue;
    public T getOldValue() {
        return oldValue;
    }

    public void setOldValue(T oldValue) {
        this.oldValue = oldValue;
    }

- BooleanValue has the equivalent, but with simpler generic resolution:

    private Boolean oldValue;

    public Boolean getOldValue() {
        return oldValue;
    }

    public void setOldValue(Boolean oldValue) {
        this.oldValue = oldValue;
    }

Result: on persistence an error occurs:

Persist project..
Exception in thread "main" [ObjectDB 2.6.9_02] javax.persistence.RollbackException
Failed to commit transaction: Failed to locate set method for field property com.greensoft.objectdb.test.entity.value.EnumValue.oldValue using reflection (error 613)
at com.objectdb.jpa.EMImpl.commit(EMImpl.java:290)
at com.greensoft.objectdb.test.console.Main.createProject(Main.java:129)
at com.greensoft.objectdb.test.console.Main.run(Main.java:250)
at com.greensoft.objectdb.test.console.Main.main(Main.java:274)
Caused by: javax.persistence.PersistenceException: com.objectdb.o.UserException: Failed to locate set method for field property com.greensoft.objectdb.test.entity.value.EnumValue.oldValue using reflection
at com.objectdb.o._PersistenceException.b(_PersistenceException.java:47)
at com.objectdb.o.JPE.g(JPE.java:145)
at com.objectdb.o.JPE.g(JPE.java:78)
... 6 more
Caused by: com.objectdb.o.UserException: Failed to locate set method for field property com.greensoft.objectdb.test.entity.value.EnumValue.oldValue using reflection
at com.objectdb.o.MSG.d(MSG.java:75)
at com.objectdb.o.UMR.P(UMR.java:937)
at com.objectdb.o.UMR$ac.i(UMR.java:1382)
at com.objectdb.o.MMM.(MMM.java:299)
at com.objectdb.o.UTY.X(UTY.java:620)
at com.objectdb.o.TYS.y(TYS.java:787)
at com.objectdb.o.TYS.x(TYS.java:639)
at com.objectdb.o.TYS.v(TYS.java:591)
at com.objectdb.o.TYM.ae(TYM.java:549)
at com.objectdb.o.TYM.ac(TYM.java:485)
at com.objectdb.o.TYM.ao(TYM.java:806)
at com.objectdb.o.TYM.at(TYM.java:891)
at com.objectdb.o.EPR.UC(EPR.java:77)
at com.objectdb.o.CLT.visitRefs(CLT.java:161)
at com.objectdb.o.TVS.j(TVS.java:169)
at com.objectdb.o.TVS.cascade(TVS.java:156)
at com.objectdb.o.STA.Q(STA.java:476)
at com.objectdb.o.STM.E(STM.java:411)
at com.objectdb.o.OBM.bP(OBM.java:931)
at com.objectdb.jdo.PMImpl.bP(PMImpl.java:2279)
at com.objectdb.o.OBM.bO(OBM.java:842)
at com.objectdb.o.OBM.bM(OBM.java:751)
at com.objectdb.jpa.EMImpl.commit(EMImpl.java:287)
... 3 more
Caused by: java.lang.NoSuchMethodException: com.greensoft.objectdb.test.entity.value.EnumValue.setOldValue(java.lang.Object)
at java.lang.Class.getDeclaredMethod(Class.java:2130)
at com.objectdb.o.UMR$ac.i(UMR.java:1368)
... 23 more

 

Analysis: inspection of the decompiled enhanced classes shows there is no explicit setOldValue(java.lang.Object) method (there is only setOldValue(T)), but there are also no explicit calls to setOldValue(java.lang.Object) within the entity class file. I don't understand why the error occurs, but setOldValue(java.lang.Object) must be called from elsewhere.

The odb logs show:

[2016-08-24 16:14:34 #15 type.registry]
New type com.greensoft.objectdb.test.entity.value.BooleanValue

[2016-08-24 16:14:34 #16 type.user]
Enhancement of type com.greensoft.objectdb.test.entity.value.BooleanValue is old and cannot be used (3308841709508783010:1622213375148932442)

[2016-08-24 16:14:34 #17 type]
Type com.greensoft.objectdb.test.entity.value.BooleanValue is not enhanced.

[2016-08-24 16:14:34 #18 type.registry]
New type com.greensoft.objectdb.test.entity.value.EnumValue

[2016-08-24 16:14:34 #19 type.user]
Enhancement of type com.greensoft.objectdb.test.entity.value.EnumValue is old and cannot be used (8514268054569000235:4597179754324543026)

[2016-08-24 16:14:34 #20 type]
Type com.greensoft.objectdb.test.entity.value.EnumValue is not enhanced.

 

The "fix": I discovered that if I include these in the IValue<T> interface the runtime error on attempting to persist disappears (but this does not "fix" the log enhancement report problem):

public interface IValue<T>  {
    ...
    T getOldValue();

    void setOldValue(T oldValue);
    ...
}

 

Case2: 

- System.setProperty("objectdb.temp.no-enhancement-crc-check", "false");

- Methods in EnumValue and BooleanValue defined as operations in interface IValue as shown above.

Result: 

The odb logs show:

[2016-08-24 16:14:34 #15 type.registry]
New type com.greensoft.objectdb.test.entity.value.BooleanValue

[2016-08-24 16:14:34 #16 type.user]
Enhancement of type com.greensoft.objectdb.test.entity.value.BooleanValue is old and cannot be used (3308841709508783010:1622213375148932442)

[2016-08-24 16:14:34 #17 type]
Type com.greensoft.objectdb.test.entity.value.BooleanValue is not enhanced.

[2016-08-24 16:14:34 #18 type.registry]
New type com.greensoft.objectdb.test.entity.value.EnumValue

[2016-08-24 16:14:34 #19 type.user]
Enhancement of type com.greensoft.objectdb.test.entity.value.EnumValue is old and cannot be used (8514268054569000235:4597179754324543026)

[2016-08-24 16:14:34 #20 type]
Type com.greensoft.objectdb.test.entity.value.EnumValue is not enhanced.

But, at least as far as persisting my model is concerned, this seem harmless.

In fact - although the log insists that BooleanValue and EnumValue are NOT enhanced - they are indeed enhanced (as one can prove using time-stamp checks and the decompiler), so the log message is inaccurate.

 

Case3:

- System.setProperty("objectdb.temp.no-enhancement-crc-check", "true"); //!

- Methods in EnumValue and BooleanValue defined as operations in interface IValue<T> as shown above.

Result: no error on attempting to persist the model, and no errors in the odb log.

 

 

 

#2

For the record, none of these problems happened with objectdb-2.6.3_04.

#3

The following test is an attempt to reproduce the reported exception:

import javax.persistence.*;

public class T1928 {

    public static void main(String[] args) {
        com.objectdb.Enhancer.enhance(
            Value.class.getName() + "," +
            BooleanValue.class.getName() + "," +
            EnumValue.class.getName()
        );

        EntityManagerFactory emf =
            Persistence.createEntityManagerFactory(
                "objectdb:db.tmp;drop");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        em.persist(new BooleanValue());
        em.persist(new EnumValue());
           em.getTransaction().commit();
        em.close();
        emf.close();       
    }
   
   
    public interface IValue<T>
    {
    }

    public static class Value<T> implements IValue<T>
    {
    }

    public interface IBooleanValue
    {
    }
   
    @Entity public static class BooleanValue extends Value<Boolean>
        implements IBooleanValue
    {
        private Boolean oldValue;
       
        public Boolean getOldValue() {
            return oldValue;
        }
    
        public void setOldValue(Boolean oldValue) {
            this.oldValue = oldValue;
        }
    }
       
    @Entity public static class EnumValue<T extends Enum<T>> extends Value<T>
    {
        private T oldValue;
        public T getOldValue() {
            return oldValue;
        }
    
        public void setOldValue(T oldValue) {
            this.oldValue = oldValue;
        }
    }
}

No errors are generated by this test case. Could you please amend this test case to produce the errors?

> Very important: I have ascertained that "true" appears to be the default behaviour !

Are you sure? It doesn't look so. Maybe you have a -Dobjectdb.temp.no-enhancement-crc-check=true in your project settings?

ObjectDB Support
#4

Replying in stages (I am preparing a console test app upload).

You asked concerning my assertion that 'I have ascertained that "true" appears to be the default behaviour !' for "objectdb.temp.no-enhancement-crc-check":

"Are you sure? It doesn't look so." 

ObjectDB log with objectdb-2.6.9_02.jar from three runs:

Run1: explicitly: System.setProperty("objectdb.temp.no-enhancement-crc-check", "false"); 

[2016-08-22 12:52:40 #15 type.registry]
New type com.greensoft.objectdb.test.entity.value.BooleanValue

[2016-08-22 12:52:40 #16 type.user]
Enhancement of type com.greensoft.objectdb.test.entity.value.BooleanValue is old and cannot be used (3308841709508783010:1622213375148932442)

[2016-08-22 12:52:40 #17 type]
Type com.greensoft.objectdb.test.entity.value.BooleanValue is not enhanced.

Run2: explicitly: System.setProperty("objectdb.temp.no-enhancement-crc-check", "true");

[2016-08-22 12:54:29 #15 type.registry]
New type com.greensoft.objectdb.test.entity.value.BooleanValue

Run3: nothing set ever (System.setProperty not called).

[2016-08-22 12:57:39 #15 type.registry]
New type com.greensoft.objectdb.test.entity.value.BooleanValue

[2016-08-22 12:57:39 #16 type.user]
Enhancement of type com.greensoft.objectdb.test.entity.value.BooleanValue is old and cannot be used (3308841709508783010:1622213375148932442)

[2016-08-22 12:57:39 #17 type]
Type com.greensoft.objectdb.test.entity.value.BooleanValue is not enhanced.

You asked:

"Maybe you have a -Dobjectdb.temp.no-enhancement-crc-check=true in your project settings?"

No.

#5

It contradicts what I said: I will double check again.

#6

You asked concerning my assertion that 'I have ascertained that "true" appears to be the default behaviour !' for "objectdb.temp.no-enhancement-crc-check":

    "Are you sure? It doesn't look so."

My apologies, I checked in my Git commits and I can see why I came to that incorrect conclusion. In a Git commit where I had the System.setProperty("objectdb.temp.no-enhancement-crc-check", ..); line commented out I also had the creation of the EnumValue case that provokes the error switched off, so the reported persistence error did not occur (and it is also why EnumValue does not appear in the ObjectDB logs). Moral: always check the ObjectDB logs as well.

But the persistence error definitely occurs (when that system property is not set or is set to "false"), as long as an EnumValue is created in my console test app am preparing upload.

#7

Console test app demonstrating error on persistence of generic EnumValue when interface IValue does not offer operation:

    void setOldValue(T oldValue);

Download from: GreensoftObjectdbTestNoweb.2016-08-22.GS4223.tgz

- Unpack:

$ tar xfz ~/Downloads/GreensoftObjectdbTestNoweb.2016-08-22.GS4223.tgz
$ cd GreensoftObjectdbTestNoweb-2016-08-22-GS4223

- Edit activation code in objectdb.conf as needed.

- Open in NetBeans8.1 and perform Clean and Build.

- ObjectDB log under /log will show:

...

[2016-08-23 00:04:25 #13 type.registry]
New type com.greensoft.objectdb.test.entity.value.IValue

[2016-08-23 00:04:25 #14 type.registry]
New type com.greensoft.objectdb.test.entity.value.Value

[2016-08-23 00:04:25 #15 type.registry]
New type com.greensoft.objectdb.test.entity.value.BooleanValue

[2016-08-23 00:04:25 #16 type.user]
Enhancement of type com.greensoft.objectdb.test.entity.value.BooleanValue is old and cannot be used (3308841709508783010:1622213375148932442)

[2016-08-23 00:04:25 #17 type]
Type com.greensoft.objectdb.test.entity.value.BooleanValue is not enhanced.

[2016-08-23 00:04:25 #18 type.registry]
New type com.greensoft.objectdb.test.entity.value.EnumValue

[2016-08-23 00:04:25 #19 type.user]
Enhancement of type com.greensoft.objectdb.test.entity.value.EnumValue is old and cannot be used (-2530522362962125572:1986273314894268403)

[2016-08-23 00:04:25 #20 type]
Type com.greensoft.objectdb.test.entity.value.EnumValue is not enhanced.
...

Execute from shell/console (not using NetBeans Run command):

$ java -cp build/classes/:lib/objectdb.jar com.greensoft.objectdb.test.console.Main

Gives output and error:

Create EntityManagerFactory ..
2016-08-23 00:12:32.946 INFO    Main []: *** Create Project and Element model ***
2016-08-23 00:12:32.950 INFO    Main []: *** Test deep value BooleanValue wrapper ***
2016-08-23 00:12:32.950 INFO    Main []: *** Test deep value EnumValue wrapper ***
2016-08-23 00:12:33.111 INFO    Main []: Persist project..
Exception in thread "main" [ObjectDB 2.6.9_02] javax.persistence.RollbackException
Failed to commit transaction: Failed to locate set method for field property com.greensoft.objectdb.test.entity.value.EnumValue.oldValue using reflection (error 613)
at com.objectdb.jpa.EMImpl.commit(EMImpl.java:290)
at com.greensoft.objectdb.test.console.Main.createProject(Main.java:148)
at com.greensoft.objectdb.test.console.Main.run(Main.java:280)
at com.greensoft.objectdb.test.console.Main.main(Main.java:305)
Caused by: javax.persistence.PersistenceException: com.objectdb.o.UserException: Failed to locate set method for field property com.greensoft.objectdb.test.entity.value.EnumValue.oldValue using reflection
at com.objectdb.o._PersistenceException.b(_PersistenceException.java:47)
at com.objectdb.o.JPE.g(JPE.java:145)
at com.objectdb.o.JPE.g(JPE.java:78)
... 6 more
Caused by: com.objectdb.o.UserException: Failed to locate set method for field property com.greensoft.objectdb.test.entity.value.EnumValue.oldValue using reflection
at com.objectdb.o.MSG.d(MSG.java:75)
at com.objectdb.o.UMR.P(UMR.java:937)
at com.objectdb.o.UMR$ac.i(UMR.java:1382)
at com.objectdb.o.MMM.<init>(MMM.java:299)
at com.objectdb.o.UTY.X(UTY.java:620)
at com.objectdb.o.TYS.y(TYS.java:787)
at com.objectdb.o.TYS.x(TYS.java:639)
at com.objectdb.o.TYS.v(TYS.java:591)
at com.objectdb.o.TYM.ae(TYM.java:549)
at com.objectdb.o.TYM.ac(TYM.java:485)
at com.objectdb.o.TYM.ao(TYM.java:806)
at com.objectdb.o.TYM.at(TYM.java:891)
at com.objectdb.o.EPR.UC(EPR.java:77)
at com.objectdb.o.CLT.visitRefs(CLT.java:161)
at com.objectdb.o.TVS.j(TVS.java:169)
at com.objectdb.o.TVS.cascade(TVS.java:156)
at com.objectdb.o.STA.Q(STA.java:476)
at com.objectdb.o.STM.E(STM.java:411)
at com.objectdb.o.OBM.bP(OBM.java:931)
at com.objectdb.jdo.PMImpl.bP(PMImpl.java:2279)
at com.objectdb.o.OBM.bO(OBM.java:842)
at com.objectdb.o.OBM.bM(OBM.java:751)
at com.objectdb.jpa.EMImpl.commit(EMImpl.java:287)
... 3 more
Caused by: java.lang.NoSuchMethodException: com.greensoft.objectdb.test.entity.value.EnumValue.setOldValue(java.lang.Object)
at java.lang.Class.getDeclaredMethod(Class.java:2130)
at com.objectdb.o.UMR$ac.i(UMR.java:1368)
... 23 more

Remarks on configuration and setup:

In com.greensoft.objectdb.test.console.Main:

    46: final static private boolean DO_OBJECTDB_NO_ENHANCEMENT_CRC_CHECK = false;

So in run() :

    269: System.setProperty("objectdb.temp.no-enhancement-crc-check", "false");

 

In com.greensoft.objectdb.test.console.Main:

    52: final static private boolean DO_TEST_ENUM_WRAPPER = true;

So an EnumValue object is built before persistence is attempted.

 

In com.greensoft.objectdb.test.entity.value.EnumValue:

@Entity
public class EnumValue<T extends Enum<T>> extends Value<T> {

...

    private T oldValue;
    public T getOldValue() {
        return oldValue;
    }

    public void setOldValue(T oldValue) {
        this.oldValue = oldValue;
    }

...

These methods are NOT offered as operations to implement (@Override) in IValue:

public interface IValue<T>  {
   
    T getValue();
   
    void setValue(T value);
   
    /**
     * TEST BUG-4232: If these are NOT included in the interface get an error in objectdb-2.6.9_02.jar !
     * This error DID NOT occur in objectdb-2.6.3_04.jar.
    */
   
    //T getOldValue();

    //void setOldValue(T oldValue);

The entity model creation is performed in Main at:

61: protected void createProject(EntityManagerFactory emf) {

log_info("*** Create Project and Element model ***");
Project project = new Project(null, "project");

Element model = new Element(project, project, "model");
project.addOwnedElement(model);

log_info("*** Test deep value BooleanValue wrapper ***");
BooleanValue bv = new BooleanValue(model, project, "boolean value", true);
model.addOwnedElement(bv);

...
if (DO_TEST_ENUM_WRAPPER) {

log_info("*** Test deep value EnumValue wrapper ***");
EnumValue<ExampleEnum> ev = new EnumValue<ExampleEnum>(model, project, "enum value", ExampleEnum.first);
model.addOwnedElement(ev);

....
}

EntityManager em = emf.createEntityManager();

log_info("Persist project..");

em.getTransaction().begin();

em.persist(project); //rely on Cascade all on ownedElements.

The reported error with EnumValue::setOldValue occurs on that attempted persistence.

 

To "fix" the error include the operations in IValue

 

public interface IValue<T>  {
    
    T getOldValue();

    void setOldValue(T oldValue);

The run again without error on persistence.

#8

In my main web app I reproduced the problem illustrated in the console test app GreensoftObjectdbTestNoweb.2016-08-22.GS4223.tgz, and the same "fix" (including the indicated operations in the IValue interface) also solves that particular reported problem:

java.lang.NoSuchMethodException: com.greensoft.objectdb.test.entity.value.EnumValue.setOldValue(java.lang.Object)

 

I am however in my web app still getting in the objectdb logs (and glassfish log console) this error:

[2016-08-23 07:57:11 #933 type.user]
Enhancement of type com.greensoft.entity.value.FloatQuantity is old and cannot be used (6859537131708849034:5119830086287281137)

[2016-08-23 07:57:11 #934 type]
Type com.greensoft.entity.value.FloatQuantity is not enhanced.

... etc ... for all generic value wrapper classes ...

This is despite using objectdb-2.6.9_02.jar and setting this in an initial @PostConstruct startup() method of a @Singleton @Startup:

System.setProperty("objectdb.temp.no-enhancement-crc-check", "true");

I have used the same strategy previously with other ObjectDB system properties, and it worked, so I am not sure why it is not taking. Using System.getProperty(...) shows it has been set, and this is definitely done before any entity-related operations.

I checked the timestamp of the enhanced entity classes, and they are time-stamped according to the Clean and Build time and Ant script post-compile enhancement. They are not affected during running (deployment to Glassfish over /build/web/WEB-INF/classes) at all. I also checked using JD-GUI decompiler that enhancement has taken place. So I don't understand why it is still reporting those 'is old and cannot be used' and 'is not enhanced' errors.

I appreciate that web apps are usually considered beyond your scope of responsibility, but I welcome any ideas or suggestions for why it might not be taking or what else I can test or diagnose.

 

 

#9

Concerning problems with web app. Definitely using ObjectDB version 2.6.9_02, checked on web app startup using tip from forum here. Definitely setting:

System.setProperty("objectdb.temp.no-enhancement-crc-check", "true");

But still getting (although does not crash web app):

Enhancement of type com.greensoft.entity.value.BooleanValue is old and cannot be used (2771047590634343651:1625572379697674392)
Enhancement of type com.greensoft.entity.value.BooleanValue is old and cannot be used (2771047590634343651:1625572379697674392)
Enhancement of type com.greensoft.entity.value.IntegerQuantity is old and cannot be used (-3489683040763700890:3228352075105864445)
Enhancement of type com.greensoft.entity.value.IntegerQuantity is old and cannot be used (-3489683040763700890:3228352075105864445)
Enhancement of type com.greensoft.entity.value.FloatQuantity is old and cannot be used (-5888151305589294889:5119830086287281137)
Enhancement of type com.greensoft.entity.value.FloatQuantity is old and cannot be used (-5888151305589294889:5119830086287281137)
Enhancement of type com.greensoft.entity.value.IntegerValue is old and cannot be used (6089093961665296172:-4341632741998532040)
Enhancement of type com.greensoft.entity.value.IntegerValue is old and cannot be used (6089093961665296172:-4341632741998532040)
Enhancement of type com.greensoft.entity.value.StringValue is old and cannot be used (4494436462157006979:3893620231063551358)
Enhancement of type com.greensoft.entity.value.StringValue is old and cannot be used (4494436462157006979:3893620231063551358)
Enhancement of type com.greensoft.entity.value.EnumValue is old and cannot be used (-211628811377316345:4541795750714405524)
Enhancement of type com.greensoft.entity.value.EnumValue is old and cannot be used (-211628811377316345:4541795750714405524)

There must be some point of difference between the web app and the console test app provided above. In the web app case the abstract Value class inherits from complex intermediate classes (too complex to describe here), so maybe something there is tripping it up.

 

#10

Build 2.6.9_05 fixes 2 bugs that are demonstrated by your new console test.

The remaining "Enhancement ... is old" error message is caused by overriding persistent properties with changed return type (in getValue) probably when using generics. ObjectDB scans methods of persistent properties using getDeclaredMethods, and in that case two versions of the getValue method are returned. Only the first was used by ObjectDB, but the order in which they were returned from getDeclaredMethods was not consistent, causing the class after enhancement to look different. The new ObjectDB build filters bridge methods, eliminating this duplication.

The other bug is when using reflection (because enhancement was detected as old) with fields of type Enum (i.e. not a specific enum but the type java.lang.Enum directly).

Both bugs exist also in build 2.6.3_04  (and probably in all 2.x builds until 2.6.9_05), so it is still unclear why your application was not affected by there issues before.

Regarding setting system properties in web applications, without getting into details, possibly the specific ObjectDB class that uses that specific system property is loaded before the property is set by your web application.

ObjectDB Support
#11

Thanks, objectdb-2.6.9_06.jar seems to work (with minimal testing) both in my test console app and main large web app project. 

Reply