Community
Participate
Working Groups
Created attachment 170500 [details] JPA Entity with problem After the call of org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getCriteriaBuilder method we get following stack trace: java.lang.NullPointerException at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.initialize(MetamodelImpl.java:370) at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.<init>(MetamodelImpl.java:101) at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.<init>(MetamodelImpl.java:120) at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.getMetamodel(EntityManagerSetupImpl.java:1956) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getMetamodel(EntityManagerFactoryImpl.java:472) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getCriteriaBuilder(EntityManagerFactoryImpl.java:456) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.invokeProxyMethod(AbstractEntityManagerFactoryBean.java:423) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean$ManagedEntityManagerFactoryInvocationHandler.invoke(AbstractEntityManagerFactoryBean.java:485) at $Proxy11.getCriteriaBuilder(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:176) at $Proxy20.getCriteriaBuilder(Unknown Source)
Created attachment 170501 [details] Entity MappedSuperClass
This issue is reproduced only in non-transactional context.
Setting target and priority. See the following page for details of what these fields mean: http://wiki.eclipse.org/EclipseLink/Development/Bugs/Guidelines
>Reverify for 2.2 - I was not aware of this issue in 2.1 >in queue but not assigned yet
>The original fix for bug # 297748 is insufficient - the updated fix will affect or preclude the fix here
>voted on bugs get raised in the priority queue >Some development history: It is assumed by the Metamodel API that metadata processing of RelationalDescriptors have their javaClass set (non-NULL) There has been several scenarios where the javaClass is null - usually on @MappedSuperclass objects documented below. bug # 303063 http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_101:_20100218:_Descriptor.javaClass_is_null_on_a_container_EM_for_a_specific_case >This issue is one of them. I think we cannot in the future "assume" that all metadata processing is complete (aka convertClassNamesToClasses() >Hi, I inserted your part-model to quickly narrow down the problem I need the entire hierarchy of this branch of your model to the root >I am missing +-- ? (possibly none) +-- AbstractAggregateRoot (likely an abstract @MappedSuperclass) >As withouth the E --> MS --> MS tree I am unable to reproduce this I thought at first it may be the UUID Basic type - but this is coming in fine It may be the UUIDConverter - but most likely what is above the ESAbstractAggregateRoot @MappedSuperclass As you can see the following trace and variable post will show that the problem would be in the section that computes the [IdentifiableType] tree. >Breakpoint during initialization org.eclipse.persistence.example.jpa.server.common.DDLGenerationClient at localhost:49849 Thread [main] (Suspended) MetamodelImpl.initialize() line: 373 MetamodelImpl.<init>(DatabaseSession) line: 101 MetamodelImpl.<init>(EntityManagerSetupImpl) line: 120 EntityManagerSetupImpl.getMetamodel() line: 2003 EntityManagerSetupImpl.deploy(ClassLoader, Map) line: 399 EntityManagerFactoryImpl.getServerSession() line: 157 EntityManagerFactoryImpl.createEntityManagerImpl(Map) line: 214 EntityManagerFactoryImpl.createEntityManager() line: 202 DDLGenerationClient.initialize(String) line: 130 DDLGenerationClient.doQuery() line: 425 DDLGenerationClient.main(String[]) line: 416 >shows us a valid processed @MappedSuperclass (that temporarily inherits from Object potentialIdentifiableType MappedSuperclassTypeImpl<X> (id=98) descriptor RelationalDescriptor (id=96) idAttributes null inheritingIdentifiableTypes HashMap<K,V> (id=145) javaClass Class<T> (org.eclipse.persistence.example.jpa.server.business.ESAbstractAggregateRoot) (id=113) members null metamodel MetamodelImpl (id=21) superType null versionAttribute null aClass Class<T> (org.eclipse.persistence.example.jpa.server.business.ESAbstractAggregateRoot) (id=113) >superclass Class<T> (java.lang.Object) (id=9) >We end up with a valid Metamodel containing your two classes User --> ESAbstractAggregateRoot tempMetaModel MetamodelImpl (id=21) entities LinkedHashMap<K,V> (id=1806) size 5 table HashMap$Entry<K,V>[16] (id=1821) [10] LinkedHashMap$Entry<K,V> (id=1826) after LinkedHashMap$Entry<K,V> (id=1827) after LinkedHashMap$Entry<K,V> (id=1820) before LinkedHashMap$Entry<K,V> (id=1826) hash 33513469 > key Class<T> (org.eclipse.persistence.example.jpa.server.business.User) (id=807) next null value EntityTypeImpl<X> (id=1799) managedTypes LinkedHashMap<K,V> (id=1807) mappedSuperclasses LinkedHashSet<E> (id=1808) map LinkedHashMap<K,V> (id=1810) size 1 table HashMap$Entry<K,V>[16] (id=1812) [12] LinkedHashMap$Entry<K,V> (id=1813) after LinkedHashMap$Entry<K,V> (id=1811) before LinkedHashMap$Entry<K,V> (id=1811) hash 14885724 key MappedSuperclassTypeImpl<X> (id=1800) descriptor RelationalDescriptor (id=1815) idAttributes HashSet<E> (id=1816) inheritingIdentifiableTypes HashMap<K,V> (id=1817) > javaClass Class<T> (org.eclipse.persistence.example.jpa.server.business.ESAbstractAggregateRoot) (id=967) members HashMap<K,V> (id=1818) metamodel MetamodelImpl (id=21) superType null versionAttribute null value Object (id=1814) types LinkedHashMap<K,V> (id=1809) size 11 table HashMap$Entry<K,V>[16] (id=1867) [1] LinkedHashMap$Entry<K,V> (id=1869) key Class<T> (java.util.UUID) (id=1877) value BasicTypeImpl<X> (id=1878) > javaClass Class<T> (java.util.UUID) (id=1877) From your @Overrides in the middle class ESAbstractAggregateRoot - it looks like you have an @Id on both levels +-- AbstractAggregateRoot (likely an abstract @MappedSuperclass) +--ESAbstractAggregateRoot (abstract @MappedSuperclass) It looks like you may have the following hierarchy Object +-- ? (possibly none) +-- AbstractAggregateRoot (likely an abstract @MappedSuperclass) +--ESAbstractAggregateRoot (abstract @MappedSuperclass) +--User (concrete @Entity) >After adding a fake AbstractAggregateRoot @MappedSuperclass above ESAbstractAggregateRoot I still process the Metamodel fine tempMetaModel MetamodelImpl (id=21) mappedSuperclasses LinkedHashSet<E> (id=62) map LinkedHashMap<K,V> (id=134) modCount 2 size 2 table HashMap$Entry<K,V>[16] (id=137) [2] LinkedHashMap$Entry<K,V> (id=139) key MappedSuperclassTypeImpl<X> (id=48) descriptor RelationalDescriptor (id=146) idAttributes HashSet<E> (id=149) map HashMap<K,V> (id=194) table HashMap$Entry<K,V>[16] (id=196) [4] HashMap$Entry<K,V> (id=198) key SingularAttributeImpl<X,T> (id=200) elementType BasicTypeImpl<X> (id=182) javaClass Class<T> (java.util.UUID) (id=205) managedType MappedSuperclassTypeImpl<X> (id=48) mapping DirectToFieldMapping (id=203) values null inheritingIdentifiableTypes HashMap<K,V> (id=150) javaClass Class<T> (org.eclipse.persistence.example.jpa.server.business.ESAbstractAggregateRoot) (id=151) members HashMap<K,V> (id=152) metamodel MetamodelImpl (id=21) superType MappedSuperclassTypeImpl<X> (id=45) [12] LinkedHashMap$Entry<K,V> (id=141) key MappedSuperclassTypeImpl<X> (id=45) descriptor RelationalDescriptor (id=159) idAttributes HashSet<E> (id=160) map HashMap<K,V> (id=209) size 1 table HashMap$Entry<K,V>[16] (id=211) [14] HashMap$Entry<K,V> (id=216) hash 22509022 key SingularAttributeImpl<X,T> (id=177) elementType BasicTypeImpl<X> (id=182) javaClass Class<T> (java.util.UUID) (id=205) managedType MappedSuperclassTypeImpl<X> (id=45) mapping DirectToFieldMapping (id=185) next null value Object (id=144) [15] null threshold 12 values null inheritingIdentifiableTypes HashMap<K,V> (id=161) javaClass Class<T> (org.eclipse.persistence.example.jpa.server.business.AbstractAggregateRoot) (id=162) members HashMap<K,V> (id=163) metamodel MetamodelImpl (id=21) superType null >So multiple UUID @Id attributes are not an issue it is likely the actual hierarchy above ESAbstractAggregateRoot or in compination with the @Converter. I will not put the bug to cannot-reproduce temporarily as a NPE is serious - I will until we get more reproduction info - add exception handling and more finest logging for this case which may be part of Could you also post the rest of this subtree hiearchy to get this reproduced. This issue is a duplicate of DI 101 in bug# 303063 http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_101:_20100218:_Descriptor.javaClass_is_null_on_a_container_EM_for_a_specific_case *** This bug has been marked as a duplicate of bug 303063 ***
Created attachment 176857 [details] Do a getServerSession that will do a login/deploy as part of an entityManagerFactory.predeploy() so all metadata processing, ddlgeneration and metamodel initialization is complete before a create em >Currently metamodel initialization is a 2-part process during emf.predeploy and em.deploy >See design issue 106 option 3 for bug # 322585 that moves everything to emf.predeploy http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_106:_20100810:_322585:Metamodel_initialization_via_EMF.getMetamodel.28.29_before_EM_deploy_results_in_an_invalid_Metamodel_because_of_UNINITIALIZED_descriptor.initializationStage After trying 2 locations of a getServerSession() call in order to do a login before an official deploy() on createEntityManager - I came across code that already exists for JPA validation that will do a login for us and effect a deploy just after the predeploy finishes on the EMF. >shouldGetSessionOnCreateFactory() >Performance Results 106-3 The following show that that the time taken to update the session, do DDL generation and intialize the metamodel and canonical metamodel has shifted to the EMF creation from the EM creation. In essence an emf.createEntityManager() now takes just a couple microseconds instead of seconds. Doing all the following in the predeploy updateServerSession session.login generateDDL metamodel initalization canonical metamodel initialization takes in SE > with change predeploy() = 2.6 sec [EL Finest]: 2010-08-17 18:01:12.002--ServerSession(27196165)--Thread(Thread[main,5,main])--Begin predeploying Persistence Unit dao.create.tables.derby; session default-session; state Initial; factoryCount 0 [EL Finest]: 2010-08-17 18:01:14.67--ServerSession(27196165)--Thread(Thread[main,5,main])--End deploying Persistence Unit dao.create.tables.derby; session default-session; state Deployed; factoryCount 1 deploy() = 0.09 sec [EL Finest]: 2010-08-17 18:01:14.67--ServerSession(27196165)--Thread(Thread[main,5,main])--End deploying Persistence Unit dao.create.tables.derby; session default-session; state Deployed; factoryCount 1 [EL Finer]: 2010-08-17 18:01:14.763--ServerSession(27196165)--Thread(Thread[main,5,main])--client acquired > without change predeploy() = 0.75 sec [EL Finest]: 2010-08-17 17:58:29.169--ServerSession(2279771)--Thread(Thread[main,5,main])--Begin predeploying Persistence Unit dao.create.tables.derby; session default-session; state Initial; factoryCount 0 [EL Finest]: 2010-08-17 17:58:29.934--ServerSession(2279771)--Thread(Thread[main,5,main])--End predeploying Persistence Unit dao.create.tables.derby; session default-session; state Predeployed; factoryCount 1 deploy() = 1.87 sec [EL Finest]: 2010-08-17 17:58:29.934--ServerSession(2279771)--Thread(Thread[main,5,main])--Begin deploying Persistence Unit dao.create.tables.derby; session default-session; state Predeployed; factoryCount 1 [EL Finer]: 2010-08-17 17:58:31.806--ServerSession(2279771)--Thread(Thread[main,5,main])--client acquired On emf.createEntityManager() we just skip deploy/login in getServerSession(), login in createEntityManagerImpl as well as deploy/login in getServerSession() in the EntityManagerImpl constructor because the emf.createEntityManager() does virtually nothing after this change EE Server testing on WebLogic 10.3.3.0 via standard @PersitenceContext injection on a SSB @EJB injected on a servlet client is OK Notice that a predeploy also does a deploy now - previously the deploy was only done when the client persisted or read from the persistence unit (via injection) Daemon Thread [[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'] (Suspended (breakpoint at line 314 in EntityManagerSetupImpl)) EntityManagerSetupImpl.deploy(ClassLoader, Map) line: 314 EntityManagerFactoryImpl.getServerSession() line: 157 PersistenceProvider.createContainerEntityManagerFactory(PersistenceUnitInfo, Map) line: 243 PersistenceUnitInfoImpl.createEntityManagerFactory(boolean) line: 352 PersistenceUnitInfoImpl.createEntityManagerFactory() line: 332 PersistenceUnitInfoImpl.<init>(PersistenceUnitBean, PersistenceUnitConfigurationBean, GenericClassLoader, String, URL, URL) line: 134 ModulePersistenceUnitRegistry(AbstractPersistenceUnitRegistry).storeDescriptors(Map, Map) line: 336 ModulePersistenceUnitRegistry(AbstractPersistenceUnitRegistry).loadPersistenceDescriptor(VirtualJarFile, boolean, File) line: 250 ModulePersistenceUnitRegistry.<init>(GenericClassLoader, ApplicationContextInternal, Module, boolean) line: 69 EJBModule.setupPersistenceUnitRegistry() line: 221 EJBModule$1.execute() line: 322 PersistenceUnitRegistryInitializer.setupPersistenceUnitRegistries() line: 62 WebAppModule.prepare() line: 398 ScopedModuleDriver.prepare() line: 176 ModuleListenerInvoker.prepare() line: 199 DeploymentCallbackFlow$1.next(Object) line: 507 StateMachineDriver.nextState(StateChange, Object[]) line: 41 DeploymentCallbackFlow.prepare(Module[]) line: 149 DeploymentCallbackFlow.prepare() line: 45 BaseDeployment$1.next(Object) line: 1221 StateMachineDriver.nextState(StateChange, Object[]) line: 41 EarDeployment(BaseDeployment).prepare(DeploymentContext) line: 367 EarDeployment.prepare(DeploymentContext) line: 58 DeploymentStateChecker.prepare(DeploymentContext) line: 154 AppContainerInvoker.prepare(DeploymentContext) line: 60 RedeployOperation.createAndPrepareContainer() line: 98 RedeployOperation.doPrepare() line: 122 RedeployOperation(AbstractOperation).prepare() line: 217 DeploymentManager.handleDeploymentPrepare(Deployment, DeploymentManager$DeploymentRequestInfo) line: 747 DeploymentManager.prepareDeploymentList(ArrayList, DeploymentContext) line: 1216 DeploymentManager.handlePrepare(DeploymentContext) line: 250 DeploymentServiceDispatcher.prepare(DeploymentContext) line: 159 DeploymentReceiverCallbackDeliverer.doPrepareCallback(DeploymentContext) line: 171 DeploymentReceiverCallbackDeliverer.access$000(DeploymentReceiverCallbackDeliverer, DeploymentContext) line: 13 DeploymentReceiverCallbackDeliverer$1.run() line: 46 SelfTuningWorkManagerImpl$WorkAdapterImpl.run() line: 528 ExecuteThread.execute(Runnable) line: 201 ExecuteThread.run()
>Fix Summary/Workaround Essentially this fix in bug # 322585 just makes validation default to true unless disabled - validation is off by default - login during emf predeploy is now on by default >workaround is to enable validation in persistence.xml The following property is named as though the persistence unit is "only" used for validation. In fact it validates the persistence unit by doing a deploy just after the predeploy - without waiting for client code to login - after that it behaves normally. This solves our issue where we may get a NPE on an unitialized descriptor's javaClass (was null) set on a Metamodel ManagedType <property name="eclipselink.validation-only" value="True"/>
Created attachment 178160 [details] Option 7 (in use): Do a getServerSession that does a deploy/login that calls initializeDescriptors only for early emf.getMetamodel() users - em.getMetamodel() users do not login
>See the fix for bug # 322585 in SVN rev# 8141 for 2.2 and 8142 for 2.1.2 https://fisheye2.atlassian.com/changelog/eclipselink/?cs=8141 We now do a preemptive DB login via getServerSession to force initializeDescriptors so that a MappedSuperclass javaClass is set on the descriptor when a client does an emf.getMetamodel() or emf.getCriteriaBuilder() before at least one EntityManager is created or logged in.
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink