Issue #473: Unexpected Exception during commit

Type: Bug ReoprtPriority: NormalStatus: FixedReplies: 5
#1

I'm testing code that otherwise has been working with a clean database. I have seen several examples of the following exception. It never seems to happen in the same place twice, though.

If you can give me a hint as to what would internally cause this, I'll try to reproduce it.

Carl

 

[ObjectDB 2.2.9_01] javax.persistence.RollbackException
Failed to commit transaction: Unexpected internal exception (error 613)
        at com.objectdb.jpa.EMImpl.commit(EMImpl.java:277)
        at com.fastmodel.fastplan.db.EntityManagerFactory.doFilter(EntityManagerFactory.java:158)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:879)
        at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
        at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
        at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
        at java.lang.Thread.run(Thread.java:662)
Caused by: com.objectdb.o.InternalException: Unexpected internal exception
        at com.objectdb.o.JPE.h(JPE.java:163)
        at com.objectdb.o.ERR.f(ERR.java:68)
        at com.objectdb.o.IVP.g(IVP.java:103)
        at com.objectdb.o.IVP.f(IVP.java:83)
        at com.objectdb.o.ISP.size(ISP.java:152)
        at com.objectdb.o.CLT.visitRefs(CLT.java:148)
        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.D(STM.java:390)
        at com.objectdb.o.OBM.bH(OBM.java:884)
        at com.objectdb.jdo.PMImpl.bH(PMImpl.java:2186)
        at com.objectdb.o.OBM.bG(OBM.java:800)
        at com.objectdb.o.OBM.bE(OBM.java:715)
        at com.objectdb.jpa.EMImpl.commit(EMImpl.java:274)
        ... 15 more
Caused by: java.lang.NullPointerException
        at com.objectdb.o.UMR.u(UMR.java:468)
        at com.objectdb.o.ENT.loadInverse(ENT.java:1281)
        at com.objectdb.o.IVP.g(IVP.java:96)
        ... 27 more

 

#2

According to the stack trace, during commit an attempt to cascade persist through an inverse (mapped by) collection field fails.

I am not sure which reference causes the NullPointerException.

The only reference in that line can never be null as far as I can tell - unless the EntityManager is in a special state that I miss.

On the next line other references that are related to the inverse field are used. Maybe that inverse reference field has special type or setting causing this problem.

 

ObjectDB Support
#3

I've found a very simple reproducible case that produces the exception every time:

    javax.persistence.EntityManagerFactory emf =
        Persistence.createEntityManagerFactory(
            "objectdb://xxxxxxxxxxxxxxx.compute-1.amazonaws.com/dev8-26.odb;user=x;password=x");

    EntityManager em = emf.createEntityManager();
    em.getTransaction().begin();

    em.find(Account.class, 1);

    em.getTransaction().commit();
    em.close();

   

I also tried upgrading to 2.2.9_05. Now when I try to enhance I get:

java.lang.NullPointerException
        at com.objectdb.o.CFG.t(CFG.java:272)
        at com.objectdb.o.CFG.r(CFG.java:193)
        at com.objectdb.o.CFG.q(CFG.java:125)
        at com.objectdb.o.JEN.<init>(JEN.java:59)
        at com.objectdb.Enhancer.enhance(Enhancer.java:66)
        at com.objectdb.Enhancer.enhance(Enhancer.java:87)
        at com.fastmodel.fastplan.db.EntityManagerFactory.contextInitialized(EntityManagerFactory.java:55)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3795)
        at org.apache.catalina.core.StandardContext.start(StandardContext.java:4252)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014)
        at org.apache.catalina.core.StandardHost.start(StandardHost.java:736)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014)
        at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
        at org.apache.catalina.core.StandardService.start(StandardService.java:448)
        at org.apache.catalina.core.StandardServer.start(StandardServer.java:700)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:552)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:295)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:433)

I also get the following on the server:

java.lang.NullPointerException
        at com.objectdb.o.CFG.t(CFG.java:272)
        at com.objectdb.o.CFG.r(CFG.java:193)
        at com.objectdb.o.CFG.q(CFG.java:125)
        at com.objectdb.Server.run(Server.java:96)
        at com.objectdb.Server.main(Server.java:66)
java.lang.NullPointerException
        at com.objectdb.o.CFG.t(CFG.java:272)
        at com.objectdb.o.CFG.r(CFG.java:193)
        at com.objectdb.o.CFG.q(CFG.java:125)
        at com.objectdb.Server.handleException(Server.java:461)
        at com.objectdb.Server.run(Server.java:113)
        at com.objectdb.Server.main(Server.java:66)
Exception in thread "main" java.lang.NullPointerException
        at com.objectdb.o.CFG.t(CFG.java:272)
        at com.objectdb.o.CFG.r(CFG.java:193)
        at com.objectdb.o.CFG.q(CFG.java:125)
        at com.objectdb.Server.handleException(Server.java:461)
        at com.objectdb.Server.run(Server.java:113)
        at com.objectdb.Server.main(Server.java:66)

I am wondering if this is related or if it is a different issue.

I will email you the src and odb file.

Thanks,

Carl

#4

The new (enhancer) exception in build 2.2.5_05 is caused by using the new build with an older configuration file.

The old (commit) exception is the result of defining an invalid mapped by field.

Build 2.2.5_06 fixes both issues and produces the following error message for your test:

Caused by: com.objectdb.error.UserException: account is not found in type Player (mapped by field com.fastmodel.fastplan.entities.Account.players)
at com.objectdb.error.ErrorMessage.construct(ErrorMessage.java:61)
at com.objectdb.type.user.UserMember.runInverseQuery(UserMember.java:467)
at com.objectdb.pc.track.EntityTracker.loadInverse(EntityTracker.java:1281)
at com.objectdb.type.inv.InverseProxy.loadCollection(InverseProxy.java:96)
... 22 more

The owner side, account, is currently defined in Person, but not in Player (and other classes).

Please notice that ObjectDB can manage collections directly with no mappedBy - and it is also much more efficient. Therefore, consider removing the mappedBy definition instead of defining the owner account field.

ObjectDB Support
#5

Many thanks for the advice and improved error messages!

A few questions about mapped collections - I do use direct collections when it makes sense from an OO perspective. I thought, however, that direct collections require loading the entire collection in order to access or alter even a single item. Is that true? In cases where I have a large number of entities that are not used as a collection, I assumed a mappedBy relationship would be better. Most often I refer to these objects directly, not as a collection. But if I need to iterate through all of them, the mapping is there for convenience.

The other thing I like about mappedBy is it gives me bi-directional navigation of my entities, even though I am only managing a reference on one side. If I used a direct collection, I would have to manage both sides. Is there a way to have bi-directional one-to-many mappings with a direct collection?

Thanks!

#6

You are right - mappedBy collections have the following advantages:

  • Small changes to very large collections may be faster.
  • Only with mappedBy you get bi-directional relationship managed automatically.

Thank you for this report.

ObjectDB Support

Reply