ObjectDB ObjectDB

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

 

edit
delete
#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
edit
delete
#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

edit
delete
#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
edit
delete
#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!

edit
delete
#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
edit
delete

Reply

To post on this website please sign in.