| The Aries transaction control integration tests have an XA integration test where two persistence units are created and used in a two phase commit. The persistence units are defined in different bundles, but use the same name for their one and only Entity Type. This name is org.apache.aries.tx.control.itests.entity.Message. The Entity types are private to the bundle, and so each one is loaded by a different class loader. In summary, the types have the same name, but are not the same (i.e. one cannot be cast to another). These tests work reliably on OpenJPA and EclipseLink, however sometimes when running on Hibernate I see the tests fail. Having step debugged the root cause is the following exception: org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [public java.lang.Integer org.apache.aries.tx.control.itests.entity.Message.id] by reflection for persistent property org.apache.aries.tx.control.itests.entity.Message#id : Message [id=null, message=Hello 1!] at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:43) at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:223) at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:4601) at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:4313) at org.hibernate.engine.internal.ForeignKeys.isTransient(ForeignKeys.java:226) at org.hibernate.event.internal.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:510) at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:99) at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:58) at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:775) at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:748) at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:753) at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1146) at org.apache.aries.tx.control.jpa.common.impl.EntityManagerWrapper.persist(EntityManagerWrapper.java:42) at org.apache.aries.tx.control.jpa.common.impl.EntityManagerWrapper.persist(EntityManagerWrapper.java:42) at org.apache.aries.tx.control.itests.XAJPATransactionTest.lambda$0(XAJPATransactionTest.java:292) at org.apache.aries.tx.control.itests.XAJPATransactionTest$$Lambda$38/892040710.call(Unknown Source) at org.apache.aries.tx.control.service.common.impl.AbstractTransactionControlImpl$TransactionBuilderImpl.doWork(AbstractTransactionControlImpl.java:155) at org.apache.aries.tx.control.service.common.impl.AbstractTransactionControlImpl$TransactionBuilderImpl.required(AbstractTransactionControlImpl.java:78) at org.apache.aries.tx.control.service.common.impl.AbstractTransactionControlImpl.required(AbstractTransactionControlImpl.java:243) at org.apache.aries.tx.control.itests.XAJPATransactionTest.testTwoPhaseCommit(XAJPATransactionTest.java:285) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:68) at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:37) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at org.junit.runner.JUnitCore.run(JUnitCore.java:115) at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.invokeViaJUnit(JUnitProbeInvoker.java:124) at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.findAndInvoke(JUnitProbeInvoker.java:97) at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.call(JUnitProbeInvoker.java:73) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.ops4j.pax.swissbox.framework.RemoteFrameworkImpl.invokeMethodOnService(RemoteFrameworkImpl.java:433) at org.ops4j.pax.swissbox.framework.RemoteFrameworkImpl.invokeMethodOnService(RemoteFrameworkImpl.java:406) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323) at sun.rmi.transport.Transport$1.run(Transport.java:178) at sun.rmi.transport.Transport$1.run(Transport.java:175) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:174) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:557) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:812) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:671) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Integer field org.apache.aries.tx.control.itests.entity.Message.id to org.apache.aries.tx.control.itests.entity.Message at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58) at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36) at java.lang.reflect.Field.get(Field.java:387) at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:39) ... 65 more This exception indicates that the EntityManagerFactory has discovered the wrong type. I confirmed this by introspecting the MetaModel, which had loaded the Entity type from persistence unit xa-test-unit-1, not xa-test-unit-2. I have attached the persistence unit descriptors if those are of interest. My guess at the source of the problem is that the scanner has found the right file in the bundle, but by the time it comes to be loaded Hibernate has lost the context of which persistence unit the type should be loaded from. If Hibernate just uses the OSGiClassLoaderService then it will find the Entity from whichever persistence unit first registered. I am not sure why this only sometimes fails. |