This Bugzilla instance is deprecated, and most Eclipse projects now use GitHub or Eclipse GitLab. Please see the deprecation plan for details.
Bug 303063 - JPA2: NPE during metamodel initialize on null containing class - ManagedType.javaClass for SingularAttribute when DirectToFieldMapping.field.type is null
Summary: JPA2: NPE during metamodel initialize on null containing class - ManagedType....
Status: RESOLVED FIXED
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows 7
: P2 major (vote)
Target Milestone: ---   Edit
Assignee: Nobody - feel free to take it CLA
QA Contact:
URL: http://wiki.eclipse.org/EclipseLink/D...
Whiteboard:
Keywords:
: 315041 (view as bug list)
Depends on: 322184 266912 282518 294765 297748 297928 320273 322166 322585
Blocks: 315041 332290
  Show dependency tree
 
Reported: 2010-02-17 09:22 EST by Michael OBrien CLA
Modified: 2022-06-09 10:24 EDT (History)
3 users (show)

See Also:


Attachments
303063 test coverage prep points for attribute override and null descriptor java class for di 50, 67 and 95 (5.04 KB, patch)
2010-02-17 16:53 EST, Michael OBrien CLA
no flags Details | Diff
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 (5.51 KB, patch)
2010-08-17 22:19 EDT, Michael OBrien CLA
no flags Details | Diff
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 (3.28 KB, patch)
2010-09-03 10:45 EDT, Michael OBrien CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Michael OBrien CLA 2010-02-17 09:22:16 EST
>reproduction test model is pending.
  It Looks like the javaClass (which resolves to clazz in PriviledgedAccessHelper) is not set on the SingularAttribute before we attempt a call on it.
>The use case is when DirectToFieldMapping.field.type is null - likely method level access

    public static Method getDeclaredMethod(final Class clazz, final String methodName, final Class[] methodParameterTypes) throws NoSuchMethodException {
         return clazz.getDeclaredMethod(methodName, methodParameterTypes);
    }

    This may be indirectly related to open issue 69 where there are occasions where we default to the String.class
http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_69:_20090831:_Object.class_as_a_default_javaType_is_not_compatible_with_JPA_1.0

    After I attempt to reproduce this (initially by hacking a SingularAttributre by clearing the javaClass to null) - the fix will be 2 parts
    1) Handle a null javaType, fail fast before attempting any operations on a null clazz - metamodel initialization should warn the user but not stop EM predeploy()
    2) determine and fix why the javaType is still not set by step 4 of the ManagedTypeImpl.getTypeClassFromAttributeOrMethodLevelAccessor() - this may involve design issue 69.
    3) step 4 needs more general NPE handling and at least some FINEST logging of this corner case

>From Mitesh M. via a user on the glassFish forum
Env: EAR on EclipseLink 2.0.0

java.lang.NullPointerException
	at java.lang.Class.searchMethods(Class.java:2646)
	at java.lang.Class.getDeclaredMethod(Class.java:1935)
	at org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getDeclaredMethod(PrivilegedAccessHelper.java:212)
	at org.eclipse.persistence.internal.jpa.metamodel.ManagedTypeImpl.getTypeClassFromAttributeOrMethodLevelAccessor(ManagedTypeImpl.java:1365)
	at org.eclipse.persistence.internal.jpa.metamodel.SingularAttributeImpl.<init>(SingularAttributeImpl.java:96)
	at org.eclipse.persistence.internal.jpa.metamodel.ManagedTypeImpl.initialize(ManagedTypeImpl.java:1295)
	at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.initialize(MetamodelImpl.java:399)
	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:1939)
	at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:385)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:151)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:207)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:195)
	at com.sun.jdo.spi.persistence.support.ejb.ejbc.PersistenceProcessor.loadPersistenceUnitBundle(PersistenceProcessor.java:573)
	at com.sun.jdo.spi.persistence.support.ejb.ejbc.PersistenceProcessor.createTablesInDB(PersistenceProcessor.java:421)
	at com.sun.jdo.spi.persistence.support.ejb.ejbc.PersistenceProcessor.processAppBundle(PersistenceProcessor.java:287)
	at com.sun.jdo.spi.persistence.support.ejb.ejbc.PersistenceProcessor.processApplication(PersistenceProcessor.java:189)
	at com.sun.jdo.spi.persistence.support.ejb.ejbc.DeploymentEventListenerImpl.processApplication(DeploymentEventListenerImpl.java:211)
	at com.sun.jdo.spi.persistence.support.ejb.ejbc.DeploymentEventListenerImpl.processEvent(DeploymentEventListenerImpl.java:172)
	at com.sun.jdo.spi.persistence.support.ejb.ejbc.DeploymentEventListenerImpl.notifyDeploymentEvent(DeploymentEventListenerImpl.java:122)
	at com.sun.enterprise.deployment.backend.DeploymentEventManager.notifyDeploymentEvent(DeploymentEventManager.java:79)
	at com.sun.enterprise.deployment.backend.AppDeployer.postDeploy(AppDeployer.java:401)
	at com.sun.enterprise.deployment.backend.AppDeployer.deploy(AppDeployer.java:260)
	at com.sun.enterprise.deployment.backend.AppDeployer.doRequestFinish(AppDeployer.java:148)
	at com.sun.enterprise.deployment.phasing.J2EECPhase.runPhase(J2EECPhase.java:208)
	at com.sun.enterprise.deployment.phasing.DeploymentPhase.executePhase(DeploymentPhase.java:108)
	at com.sun.enterprise.deployment.phasing.PEDeploymentService.executePhases(PEDeploymentService.java:966)
	at com.sun.enterprise.deployment.phasing.PEDeploymentService.deploy(PEDeploymentService.java:280)
	at com.sun.enterprise.deployment.phasing.PEDeploymentService.deploy(PEDeploymentService.java:298)
	at com.sun.enterprise.admin.mbeans.ApplicationsConfigMBean.deploy(ApplicationsConfigMBean.java:584)
	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 com.sun.enterprise.admin.MBeanHelper.invokeOperationInBean(MBeanHelper.java:390)
	at com.sun.enterprise.admin.MBeanHelper.invokeOperationInBean(MBeanHelper.java:373)
	at com.sun.enterprise.admin.config.BaseConfigMBean.invoke(BaseConfigMBean.java:477)
	at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:836)
	at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:761)
	at sun.reflect.GeneratedMethodAccessor14.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.sun.enterprise.admin.util.proxy.ProxyClass.invoke(ProxyClass.java:90)
	at $Proxy1.invoke(Unknown Source)
	at com.sun.enterprise.admin.server.core.jmx.SunoneInterceptor.invoke(SunoneInterceptor.java:304)
	at com.sun.enterprise.interceptor.DynamicInterceptor.invoke(DynamicInterceptor.java:170)
	at com.sun.enterprise.deployment.autodeploy.AutoDeployer.invokeDeploymentService(AutoDeployer.java:583)
	at com.sun.enterprise.deployment.autodeploy.AutoDeployer.deployJavaEEArchive(AutoDeployer.java:564)
	at com.sun.enterprise.deployment.autodeploy.AutoDeployer.deploy(AutoDeployer.java:495)
	at com.sun.enterprise.deployment.autodeploy.AutoDeployer.deployAll(AutoDeployer.java:270)
	at com.sun.enterprise.deployment.autodeploy.AutoDeployControllerImpl$AutoDeployTask.run(AutoDeployControllerImpl.java:374)
	at java.util.TimerThread.mainLoop(Timer.java:512)
	at java.util.TimerThread.run(Timer.java:462)
Comment 1 Michael OBrien CLA 2010-02-17 09:24:30 EST
>In reproduction
Comment 2 Michael OBrien CLA 2010-02-17 11:13:51 EST
>We assume that the RelationalDescriptor always has a javaClass set in the ManagedType constructor - we may need to revisit this

    protected ManagedTypeImpl(MetamodelImpl metamodel, RelationalDescriptor descriptor) {
        // A valid descriptor will always have a javaClass set
        super(descriptor.getJavaClass());


>We will want to review the population of the ManagedType.javaClass for @MappedSuperclass types
>see the fix for DI 32 in bug# 282518
http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_32:_20090703:_Metamodel_superType_requires_javaClass_set_on_custom_descriptor_on_MappedSuperclassAccessor
http://fisheye2.atlassian.com/changelog/eclipselink/?cs=4614
https://bugs.eclipse.org/bugs/show_bug.cgi?id=282518


>Investigation - I used to check for a null javaClass on the containing type but this code was removed to assume that descriptor.javaClass is allways set

http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_50:_20090727:_Handle_all_mapping_types_in_the_SingularAttribute_constructor

>this was modified in SVN rev# 5050 for DI 67
http://fisheye2.atlassian.com/changelog/eclipselink/?cs=5050
http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_67:20090827:_AggregateCollectionMapping_support_in_PluralAttribute

>see 
http://fisheye2.atlassian.com/browse/eclipselink/trunk/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metamodel/SingularAttributeImpl.java?r1=4969&r2=5050

>
            } else if (mapping.isDirectToFieldMapping()) { // Also handles the keys of an EmbeddedId
                attributeClass = mapping.getField().getType();
                if(null == attributeClass) {
                    // lookup the attribute on the containing class                    
                    Class containingClass = mapping.getDescriptor().getJavaClass();
                    Field aField = null;
                    try {
                        aField = containingClass.getDeclaredField(mapping.getAttributeName());
                        attributeClass = aField.getType();
                    } catch (NoSuchFieldException nsfe) {
                        // This exception will be warned about below
                        //nsfe.printStackTrace();
                    }                    
                }
                // all Direct mappings that don't have a type on their field
                if(null == attributeClass && validationEnabled) {
                    // TODO: refactor
                    attributeClass = Object.class;
                    AbstractSessionLog.getLog().log(SessionLog.FINEST, "metamodel_attribute_class_type_is_null", this);                    
                }

>This functionality should be replaced and extended
Comment 3 Michael OBrien CLA 2010-02-17 11:46:17 EST
>See original java.net GlassFish forum thread 74881
http://forums.java.net/jive/thread.jspa?threadID=74881&tstart=0
Comment 4 Michael OBrien CLA 2010-02-17 16:53:41 EST
Created attachment 159387 [details]
303063 test coverage prep points for attribute override and null descriptor java class for di 50, 67 and 95
Comment 5 Michael OBrien CLA 2010-02-17 17:11:46 EST
>Issue 1: are we running one of the following unsupported configurations?

    /** Default elementType Class when we the type cannot be determined for unsupported mappings such as Transformation and VariableOneToOne */
    public static final Class DEFAULT_ELEMENT_TYPE_FOR_UNSUPPORTED_MAPPINGS = Object.class;

>Issue 2: for Method level access (property as opposed to field) - are we using attribute overrides?
Comment 6 Michael OBrien CLA 2010-02-18 09:53:57 EST
>Customer is also having issues with type-converter and bytea not being converted to an ID.
>Env is GlassFish 2.1.1 on PostgreSQL (v?) using orm.xml as opposed to annotations.
Comment 7 Michael OBrien CLA 2010-02-18 10:32:11 EST
>See SVN rev# 6312 for a first fix of the NPE (allows non-metamodel users to continue with deploy()
   We met about your issue this morning with management.  I was referred to a fix put in for EclipseLink 2.0.1 that I forgot about - but I reviewed.  It should solve your issue with metamodel initialization - in that any unforseen exceptions do not derail the EM deploy().

See the following fix that went into the 6312 build on 19 Jan 2010
http://fisheye2.atlassian.com/browse/eclipselink/branches/2.0/trunk/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/EntityManagerSetupImpl.java?r1=5935&r2=6312

  385  -             this.getMetamodel();             
  385 +             try { 
  386 +                 this.getMetamodel(); 
  387 +             } catch (Exception e) { 
  388 +                 session.log(SessionLog.FINEST, SessionLog.METAMODEL, "metamodel_init_failed", new Object[]{e.getMessage()}); 
  389 +             } 

You may download the latest EclipseLink 2.0.1 jar and test the fix below.
http://www.eclipse.org/eclipselink/downloads/index.php
Comment 8 Michael OBrien CLA 2010-02-18 12:05:48 EST
>Test results on the Glassfish V2.1.1 container with a forced NPE in MetamodelImpl.initialize() to verify that any exception does not stop EM deploy()


Daemon Thread [httpSSLWorkerThread-8080-0] (Suspended (breakpoint at line 391 in EntityManagerSetupImpl))	
	EntityManagerSetupImpl.deploy(ClassLoader, Map) line: 391	
	EntityManagerFactoryImpl.getServerSession() line: 153	
	EntityManagerFactoryImpl.createEntityManagerImpl(Map) line: 210	
	EntityManagerFactoryImpl.createEntityManager() line: 198	

this	EntityManagerSetupImpl  (id=154)	
realClassLoader	WebappClassLoader  (id=156)	
additionalProperties	HashMap<K,V>  (id=163)	
deployProperties	HashMap<K,V>  (id=188)	
e	NullPointerException  (id=271)	
	backtrace	 (id=279)	
	cause	null	
	detailMessage	null	
	noBackTrace	0	
	stackTrace	null	
	stackTraceHolder	null	

>Stack trace shows the exception log and the normal functioning of the persistence unit after a sucessfull deploy on an EE container

[#|2010-02-18T10:54:21.770-0500|INFO|sun-appserver2.1|javax.enterprise.system.container.web|_ThreadID=10;_ThreadName=Main Thread;Sun GlassFish Enterprise Server v2.1.1;|WEB0302: Starting Sun GlassFish Enterprise Server v2.1.1|#]
[#|2010-02-18T11:32:08.265-0500|INFO|sun-appserver2.1|org.eclipse.persistence.session.file:/C:/opt/glassfish/domains/domain1/applications/j2ee-apps/org.eclipse.persistence.example.jpa.server.glassfishv2.EnterpriseEAR/org.eclipse.persistence.example.jpa.server.glassfishv2.EnterpriseWeb_war/WEB-INF/classes/_enterprise|_ThreadID=18;_ThreadName=httpSSLWorkerThread-8080-0;|file:/C:/opt/glassfish/domains/domain1/applications/j2ee-apps/org.eclipse.persistence.example.jpa.server.glassfishv2.EnterpriseEAR/org.eclipse.persistence.example.jpa.server.glassfishv2.EnterpriseWeb_war/WEB-INF/classes/_enterprise login successful|#]
>Exception is logged, ignored and deploy() continues OK
>[#|2010-02-18T11:34:50.209-0500|FINEST|sun-appserver2.1|org.eclipse.persistence.session.file:/C:/opt/glassfish/domains/domain1/applications/j2ee-apps/org.eclipse.persistence.example.jpa.server.glassfishv2.EnterpriseEAR/org.eclipse.persistence.example.jpa.server.glassfishv2.EnterpriseWeb_war/WEB-INF/classes/_enterprise.jpa_metamodel|_ThreadID=18;_ThreadName=httpSSLWorkerThread-8080-0;ClassName=null;MethodName=null;_RequestID=ae1cab38-c772-4018-92ec-28166a69681e;|Initialization of the medamodel failed during deployment.  Ignoring exception: [null] |#]
[#|2010-02-18T11:35:26.292-0500|FINEST|sun-appserver2.1|org.eclipse.persistence.session.file:/C:/opt/glassfish/domains/domain1/applications/j2ee-apps/org.eclipse.persistence.example.jpa.server.glassfishv2.EnterpriseEAR/org.eclipse.persistence.example.jpa.server.glassfishv2.EnterpriseWeb_war/WEB-INF/classes/_enterprise.properties|_ThreadID=18;_ThreadName=httpSSLWorkerThread-8080-0;ClassName=null;MethodName=null;_RequestID=ae1cab38-c772-4018-92ec-28166a69681e;|End deploying Persistence Unit enterprise; session file:/C:/opt/glassfish/domains/domain1/applications/j2ee-apps/org.eclipse.persistence.example.jpa.server.glassfishv2.EnterpriseEAR/org.eclipse.persistence.example.jpa.server.glassfishv2.EnterpriseWeb_war/WEB-INF/classes/_enterprise; state Deployed; factoryCount 1|#]
[#|2010-02-18T11:35:30.301-0500|FINEST|sun-appserver2.1|org.eclipse.persistence.session.file:/C:/opt/glassfish/domains/domain1/applications/j2ee-apps/org.eclipse.persistence.example.jpa.server.glassfishv2.EnterpriseEAR/org.eclipse.persistence.example.jpa.server.glassfishv2.EnterpriseWeb_war/WEB-INF/classes/_enterprise.query|_ThreadID=18;_ThreadName=httpSSLWorkerThread-8080-0;ClassName=null;MethodName=null;_RequestID=ae1cab38-c772-4018-92ec-28166a69681e;|Execute query ReadAllQuery(name="references" referenceClass=Cell sql="SELECT t1.ID, t1.STATE, t1.TSEQ, t1.RIGHT_ID FROM EL_CELL_EL_CELL t0, EL_CELL t1 WHERE ((t0.peers_ID = ?) AND (t1.ID = t0.references_ID))")|#]
[#|2010-02-18T11:35:31.003-0500|FINE|sun-appserver2.1|org.eclipse.persistence.session.file:/C:/opt/glassfish/domains/domain1/applications/j2ee-apps/org.eclipse.persistence.example.jpa.server.glassfishv2.EnterpriseEAR/org.eclipse.persistence.example.jpa.server.glassfishv2.EnterpriseWeb_war/WEB-INF/classes/_enterprise.sql|_ThreadID=18;_ThreadName=httpSSLWorkerThread-8080-0;ClassName=null;MethodName=null;_RequestID=ae1cab38-c772-4018-92ec-28166a69681e;|SELECT t1.ID, t1.STATE, t1.TSEQ, t1.RIGHT_ID FROM EL_CELL_EL_CELL t0, EL_CELL t1 WHERE ((t0.peers_ID = ?) AND (t1.ID = t0.references_ID))
	bind => [880]|#]


>The medamodel metamodel log text was fixed for SVN rev # 6310 (trunk, 2.0.1, 2.0.2 only)
http://fisheye2.atlassian.com/changelog/eclipselink/?cs=6622
Rev# 6312 (2.0) is OK
http://fisheye2.atlassian.com/browse/eclipselink/branches/2.0/trunk/jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/EntityManagerSetupImpl.java?r=6312
6310 (trunk) is modified
http://fisheye2.atlassian.com/browse/eclipselink/trunk/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/localization/i18n/TraceLocalizationResource.java?r=6310#l318

A full fix will be posted to bug# 303063
Comment 9 Michael OBrien CLA 2010-02-18 17:20:34 EST
>I have a start at a reproduction - thanks to Spring 3.0.1 - it is a descriptor initialization timing issue
>The javaClassName is set, the javaClass is still null - before we use it.
see
http://jira.springframework.org/browse/SPR-6826?page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel

>The above single Entity runs fine in SE, but fails on the spring container using the weaving agent
-javaagent:c:\opt\spring3\org.springframework.instrument-3.0.0.RELEASE.jar
for
	    <property name="loadTimeWeaver">
			<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
		</property>
Comment 10 Michael OBrien CLA 2010-02-18 17:32:40 EST
>Even with NPE handlers we need to fix the root lazy-set-javaClass in descriptor problem because criteria/metamodel users will still fail
>on an AbstractQueryImpl.from() for example - when standard JPA 2 type checking is applied

Caused by: java.lang.IllegalArgumentException: The type [null] is not the expected [EntityType] for the key class [class model.Customer].
	at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.entity(MetamodelImpl.java:152)
	at org.eclipse.persistence.internal.jpa.querydef.AbstractQueryImpl.from(AbstractQueryImpl.java:97)
	at dao.impl.TestDao.getCustomerBySurname(TestDao.java:34)
Comment 11 Michael OBrien CLA 2010-02-18 23:15:03 EST
>For Spring containerMode=true at least...
>It looks like we are not calling Project.convertClassNamesToClasses during the deploy call from LocalContainerEntityManagerFactoryBean when the injected EntityManager is deployed
Normally this happens after predeploy() during createEntityManager for an SE app - I am debugging an EE app on either WebLogic/JBoss/GlassFish to verify


>On Spring in this case - the Metadata javaClass and descriptor.javaClassName are set (but not the javaClass yet)
Thread [main] (Suspended)	
	MetadataDescriptor.setJavaClass(MetadataClass) line: 1510	
	MetadataDescriptor.<init>(MetadataClass) line: 214	
	EntityAccessor(ClassAccessor).<init>(MetadataAnnotation, MetadataClass, MetadataProject) line: 171	
	EntityAccessor(MappedSuperclassAccessor).<init>(MetadataAnnotation, MetadataClass, MetadataProject) line: 180	
	EntityAccessor.<init>(MetadataAnnotation, MetadataClass, MetadataProject) line: 136	
	MetadataProcessor.initPersistenceUnitClasses() line: 268	
	MetadataProcessor.processEntityMappings() line: 446	
	PersistenceUnitProcessor.processORMetadata(MetadataProcessor, boolean) line: 386	
	EntityManagerSetupImpl.predeploy(PersistenceUnitInfo, Map) line: 947	
	PersistenceProvider.createContainerEntityManagerFactory(PersistenceUnitInfo, Map) line: 202	
	LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory() line: 225	
	

>normally this happens for an SE EM or an application managed EM on an EE server
Thread [main] (Suspended (breakpoint at line 4070 in ClassDescriptor))	
	RelationalDescriptor(ClassDescriptor).setJavaClass(Class) line: 4070	
	RelationalDescriptor(ClassDescriptor).convertClassNamesToClasses(ClassLoader) line: 1266	
	Project.convertClassNamesToClasses(ClassLoader) line: 362	
	EntityManagerSetupImpl.deploy(ClassLoader, Map) line: 322	
	EntityManagerFactoryImpl.getServerSession() line: 153	
	EntityManagerFactoryImpl.createEntityManagerImpl(Map) line: 210	
	EntityManagerFactoryImpl.createEntityManager() line: 198	
	PersistenceService.initialize() line: 32	
	PersistenceService.persistObjects(List) line: 136	
	PersistenceService.persistHyperCube() line: 96	
	Client.doTableGeneration() line: 14	
	Client.main(String[]) line: 25	

>On the GlassFish server
GlassFish v2.1.1 Java EE 5 at localhost [Application Server (GlassFish or Sun)]	
	BEA JRockit(R)[localhost:9009]	
		Thread [Thread-21] (Running)	
		Thread [SelectorThread-8080] (Running)	
		Daemon Thread [httpSSLWorkerThread-8080-0] (Suspended (breakpoint at line 4070 in ClassDescriptor))	
			RelationalDescriptor(ClassDescriptor).setJavaClass(Class) line: 4070	
			RelationalDescriptor(ClassDescriptor).convertClassNamesToClasses(ClassLoader) line: 1266	
			Project.convertClassNamesToClasses(ClassLoader) line: 362	
			EntityManagerSetupImpl.deploy(ClassLoader, Map) line: 324	
			EntityManagerFactoryImpl.getServerSession() line: 153	
			EntityManagerFactoryImpl.createEntityManagerImpl(Map) line: 210	
			EntityManagerFactoryImpl.createEntityManager() line: 198	
			ApplicationManagedService.initialize(String) line: 38	

>In Spring we go directly to weaving instead (where there is no Project.convertClassNamesToClasses() call in a deploy from Springs' LocalContainerEntityManagerFactoryBean
where className=model/Customer
[EL Finest]: 2010-02-18 22:29:32.367--ServerSession(4940455)--Thread(Thread[main,5,main])--Begin weaver class transformer processing class [model/Customer].
>Note the difference from WebLogic weaving where the className uses "." package delimiters instead of "/" slashes
[EL Finest]: 2010-01-20 10:01:32.274--ServerSession(8493003)--Thread(Thread[[ACTIVE] ..])--Begin weaver class transformer processing class [org.eclipse.persistence.example.business.Cell].
>should not be an issue as the byte code is loaded

Thread [main] (Suspended (breakpoint at line 91 in PersistenceWeaver))	
	PersistenceWeaver.transform(ClassLoader, String, Class, ProtectionDomain, byte[]) line: 91	
	ClassFileTransformerAdapter.transform(ClassLoader, String, Class<?>, ProtectionDomain, byte[]) line: 56	
	InstrumentationLoadTimeWeaver$FilteringClassFileTransformer.transform(ClassLoader, String, Class<?>, ProtectionDomain, byte[]) line: 181	
	TransformerManager.transform(ClassLoader, String, Class, ProtectionDomain, byte[]) line: 169	
	InstrumentationImpl.transform(ClassLoader, String, Class, ProtectionDomain, byte[], boolean) line: 365	

>The result of this is we later place the descriptor into a map using a null key
{null=RelationalDescriptor(model.Customer --> [DatabaseTable(CUSTOMER)])}
However the null key really has no effect since we are only iterating the values - it is the lookup of this null javaClass that is causing the issue.

Thread [main] (Suspended)	
	HashMap<K,V>.putForNullKey(V) line: 393	
	HashMap<K,V>.put(K, V) line: 371	
	Project.getDescriptors() line: 553	
	ServerSession(AbstractSession).getDescriptors() line: 1722	
	MetamodelImpl.initialize() line: 319	
	MetamodelImpl.<init>(DatabaseSession) line: 101	
	MetamodelImpl.<init>(EntityManagerSetupImpl) line: 120	
	EntityManagerSetupImpl.getMetamodel() line: 1968	
	EntityManagerFactoryImpl.getMetamodel() line: 480	
	EntityManagerFactoryImpl.getCriteriaBuilder() line: 463	
	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
	NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39	
	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25	
	Method.invoke(Object, Object...) line: 597	
	AbstractEntityManagerFactoryBean$ManagedEntityManagerFactoryInvocationHandler.invoke(Object, Method, Object[]) line: 431	
	$Proxy6.getCriteriaBuilder() line: not available
Comment 12 Michael OBrien CLA 2010-02-19 14:55:05 EST
>The original 2 issues for the forum post below have been solved by the upgrade to EclipseLink 2.0.1 from 2.0.0 - no more NPE and no more issues with bytea
>The remaining base issue of the corner case where convertClassNamesToClasses() is not called during deploy() is being worked on before we close this bug.
Comment 13 Michael OBrien CLA 2010-03-01 10:00:09 EST
>See possible required catalina on JBoss 5.1.0 non-jta-datasource (jta-datasource is fine) datasource session customizer STRING_LOOKUP required for bug# 260383
Comment 14 Michael OBrien CLA 2010-03-05 10:50:55 EST
>This issue requires a entity/mappedSuperclass reproduction and needs to be scheduled
>The spring SPR-6826 issue where their container callback does not end up calling convertClassNamesToClasses
>is the same cause but is unrelated and is a Spring container issue
Comment 15 Michael OBrien CLA 2010-03-08 14:17:04 EST
>update: no reproduction (so-far) in our JPA test model
>See clover code coverage results (0 hits for 22834 constructor calls
> (no null javaClass passed to Metamodel API during deploy()

 118  22834      protected ManagedTypeImpl(MetamodelImpl metamodel, RelationalDescriptor descriptor) {
 ...
 124             // 303063: secondary check for case where descriptor has no java class set - should never happen but this will show on code coverage 
 125  22834          if(null == this.getJavaType()) {
> 126  0              AbstractSessionLog.getLog().log(SessionLog.FINEST, "metamodel_relationaldescriptor_javaclass_null_on_managedType", descriptor, this);
 127             }
Comment 16 Michael OBrien CLA 2010-03-22 11:23:18 EDT
>Work is on hold pending a reproduction model
Comment 17 Michael OBrien CLA 2010-07-19 09:56:26 EDT
>We have a user request possibly for this fix that requires investigation
http://forums.java.net/jive/message.jspa?messageID=399285#399285
Comment 18 Michael OBrien CLA 2010-07-19 10:31:24 EDT
>see related Spring 3.0 JIRA SPR-6826
https://jira.springsource.org/browse/SPR-6826
Comment 20 Michael OBrien CLA 2010-08-06 13:11:11 EDT
*** Bug 315041 has been marked as a duplicate of this bug. ***
Comment 21 Michael OBrien CLA 2010-08-10 11:06:22 EDT
>See related bug# 297928 (using the Metamodel via EntityManagerFactory before creating an EntityManager - where all descriptors are fully initialized)
>Attempting to reproduce the user state for bug# 303063 where the javaClass is null during Metamodel initialization resulted in the following
We have the following sequence of operations
- 1) predeploy for each persistence unit
			EntityManagerSetupImpl.predeploy(PersistenceUnitInfo, Map) line: 837	
     1a) in each predeploy we process metadata (used later by the Metamodel)
			PersistenceUnitProcessor.processORMetadata(MetadataProcessor, boolean) line: 432	

- 2) predeploy complete - we attempt to get the metamodel from the EMF (this is INVALID)
EntityManagerSetupImpl.getMetamodel() line: 2003	
- 3) we fail on an uninitialized descriptor during metamodel processing
RelationalDescriptor(ClassDescriptor).getJavaClass() line: 2055	
EmbeddableTypeImpl<X>(ManagedTypeImpl<X>).<init>(MetamodelImpl, RelationalDescriptor) line: 128	


>Processing Embeddables and MappedSuperclasses at this point is invalid because of the getMetamodel() call between the predeploy() and deploy() - descriptors (the entities) are not initialized yet
>How would one get to this point? do a getMetamodel() on the EntityManagerFactory before the EntityManager is deployed in EE or SE

>In the embeddable desriptor below the initializationStage == 0 == UNINITIALIZED
We need stage INITIALIZED == 2 (we dont need POST_INITIALIZED == 3)
this	RelationalDescriptor  (id=290)	
	initializationStage	0	
	javaClass	null	
	javaClassName	"org.eclipse.persistence.testing.models.jpa.metamodel.EmbeddedPK" (id=308)	
	wrapperPolicy	null	

>Fix: add a check for initializationStatus() during a ClassDeescriptor.getJavaClass() call from Metamodel API
Warn that Metamodel initialization is not possible before deployment has finished as the descriptor is not fully initialized
Comment 22 Michael OBrien CLA 2010-08-17 22:19:07 EDT
Created attachment 176854 [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

>See design issue 106 option 3 for bug # 322585
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() line: 173
Comment 23 Michael OBrien CLA 2010-08-18 08:30:15 EDT
>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"/>
Comment 24 Michael OBrien CLA 2010-09-03 10:45:12 EDT
Created attachment 178156 [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
Comment 25 Michael OBrien CLA 2010-09-03 15:20:32 EDT
>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.
If a NullPointerException occurs on early post-predeploy but pre-deploy access to the Metamodel via an EntityManagerFactory.getMetamodel() or emf.getCriteriaBuilder() call before an initial login to the DB - then reopen this bug.
NPE in ManagedTypeImpl.getTypeClassFromAttributeOrMethodLevelAccessor
NPE in MetamodelImpl.initialize
Comment 26 Michael OBrien CLA 2010-12-23 12:56:33 EST
>see possible duplicate in bug # 332290 on rev # 8050 which is lower than the 8141 fix
Comment 27 Michael OBrien CLA 2011-01-13 09:28:24 EST
>bug 332290 was closed as fixed by rev 8141 in bug # 322585
http://www.eclipse.org/forums/index.php?t=msg&th=170950&start=0
Comment 28 Michael OBrien CLA 2011-03-03 13:20:17 EST
>in reply to comment # 10

>The workaround for DI 101 and bug# 338837 fix the IAE issue for Criteria/Metamodel users attempting to use an EntityType that is not found

Exception in thread "main" java.lang.IllegalArgumentException: The type [null] is not the expected [EntityType] for the key class [class org.eclipse.persistence.example.distributed.collatz.model.UnitOfWork].

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

>workaround is
<exclude-unlisted-classes>false</exclude-unlisted-classes>
or
<class>org.eclipse.persistence.example.distributed.collatz.model.UnitOfWork</class>
Comment 29 Eclipse Webmaster CLA 2022-06-09 10:24:23 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink