Adding EntityListener Throws Unexpected Internal Exception

#1

I tried adding EntityListener for a entity class and an exception was thrown. I followed similar as mentioned on the documentation but no luck.

My entity class looks like below:

@Entity
@EntityListeners(MyListener.class)
public class Product extends BaseModel<Product> {

    public Product() {
        super(Product.class);
    }

    @MapsId
    @ManyToOne(fetch = FetchType.LAZY)
    private SomeClass someClass;

    ... Setter/Getter, Map, Enum & other primitive fields..
}

and listener like below:

public class MyListener {

    @PostLoad
    public void onPostLoad(Object o) {
        Logger.info("PostLoad call.");
    }

    @PreUpdate
    public void onPreRemove(Object o) {
        Logger.info("PreUpdate call.");
    }
}

And this throws an error every time I persist or update.

[error] application - message= Unexpected internal exception, cause= [ObjectDB 2.5.4] Unexpected exception (Error 990)
  Generated by Java HotSpot(TM) 64-Bit Server VM 1.8.0 (on Linux 3.2.0-57-generic).

Please report this error on http://www.objectdb.com/database/issue/new
com.objectdb.o.InternalException: java.lang.NullPointerException: null
java.lang.NullPointerException
at com.objectdb.o.ANT.R(ANT.java:792)
at com.objectdb.o.ANT.Q(ANT.java:772)
at com.objectdb.o.JPA.b(JPA.java:150)
at com.objectdb.o.SCM.r(SCM.java:239)
at com.objectdb.o.TYS.n(TYS.java:294)
at com.objectdb.o.TYM.ae(TYM.java:521)
at com.objectdb.o.TYM.ac(TYM.java:467)
at com.objectdb.o.TYM.ao(TYM.java:788)
at com.objectdb.o.TYM.at(TYM.java:873)
at com.objectdb.o.TVS.g(TVS.java:93)
at com.objectdb.o.EMR.q(EMR.java:76)
at com.objectdb.jpa.EMImpl.merge(EMImpl.java:514)
at models.core.db.objectdb.ObjectDBBaseModel.update(ObjectDBBaseModel.java:75)
at data.DataDev.addDefaultProduct(DataDev.java:164)
at data.DataDev.lambda$insert$5(DataDev.java:136)
at data.DataDev$$Lambda$2/2130689326.invoke(Unknown Source)
at play.db.jpa.JPA$1.apply(JPA.java:106)
at play.db.jpa.JPA$1.apply(JPA.java:104)
at play.db.jpa.JPA.withTransaction(JPA.java:135)
at play.db.jpa.JPA.withTransaction(JPA.java:104)
at data.DataDev.insert(DataDev.java:113)
at Global.onStart(Global.java:154)
at play.core.j.JavaGlobalSettingsAdapter.onStart(JavaGlobalSettingsAdapter.scala:22)
at play.api.GlobalPlugin.onStart(GlobalSettings.scala:220)
at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:91)
at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:91)
at scala.collection.immutable.List.foreach(List.scala:383)
at play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:91)
at play.api.Play$$anonfun$start$1.apply(Play.scala:91)
at play.api.Play$$anonfun$start$1.apply(Play.scala:91)
at play.utils.Threads$.withContextClassLoader(Threads.scala:21)
at play.api.Play$.start(Play.scala:90)
at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:142)
at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:115)
at scala.Option.map(Option.scala:145)
at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:115)
at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:113)
at scala.util.Success.flatMap(Try.scala:230)
at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:113)
at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:105)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
at scala.concurrent.forkjoin.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1361)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

So what have I done wrong on this? A bug maybe on objectdb?

#2

This is an unexpected exception.

It is thrown during analysis of the listener class in the following ObjectDB code:

    for (Class l = listenerClass; l != Object.class; l = l.getSuperclass()) {
        for (Method method : l.getDeclaredMethods()) { // <= Here is the NullPointerException
            ...
        }
    }

Can you reproduce the exception in a console application? If you try the code above on your listener class in a console application, probably no exception will be thrown, so it may be related somehow to your environment and class loading.

ObjectDB (in the code above) assumes that the listener class is a descendant of the same java.lang.Object class that ObjectDB uses. Theoretically if there is more than one Object class (loaded by different class loaders, although this is unexpected) then this code could cause NullPointerException.

If this is the case, we can easily provide a fix. Could you please check in this context the super class of your listener class and the super class of com.objectdb.Utilities, is it the same Object.class?

ObjectDB Support
#3

Case is closed. Thank you!

I checked the imports and there was a similar class having same name. 

I was using the wrong listener class. Now its working like charm.

#4

Maybe it was not a class but an interface?

The loop in #2 above assumes that it is a class. Interfaces are not descendant of java.lang.Object.

Anyway, a better error message should be produced in this case, so thanks for the report.

ObjectDB Support

Reply