5.2.14 regression: NullPointerException in AbstractPropertyMapping.getSuperCollection
Description
Attachments
- 07 Mar 2018, 03:18 PM
caused by
causes
duplicates
is duplicated by
Activity
Andrea BorieroMarch 7, 2018 at 2:25 PM
Hi @Andrej Golovnin, thanks a lot for testing the PR and for the quick feedback.
Andrej GolovninMarch 7, 2018 at 2:04 PM
@Christian Beikov Looks good. All tests are green now. Thanks a lot for quick fix!
Christian BeikovMarch 7, 2018 at 12:37 PM
@Andrej I was able to reproduce the issue. I updated the PR to incorporate a test and fix: https://github.com/hibernate/hibernate-orm/pull/2180
We will most probably revert the fix for https://hibernate.atlassian.net/browse/HHH-11544#icft=HHH-11544 in 5.2.15 yet I'd like to ask you to test the PR to verify all edge cases are handled.
Guillaume SmetMarch 7, 2018 at 12:24 PM
Hi @Andrej Golovnin,
Thanks for testing. It will be hard to understand what's going on without a test case.
Could you add a conditional breakpoint where the NPE is so that you can have more context about the types. It might help isolating the issue and getting a test case.
Thanks!
Andrej GolovninMarch 7, 2018 at 11:39 AM
@Christian Beikov Even with the changes from the pull request, there is still a problem:
Caused by: org.hibernate.MappingException: Could not instantiate persister org.hibernate.persister.entity.UnionSubclassEntityPersister
at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:112)
at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:77)
at org.hibernate.metamodel.internal.MetamodelImpl.initialize(MetamodelImpl.java:128)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:302)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:460)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:892)
... 39 more
Caused by: java.lang.NullPointerException
at org.hibernate.persister.entity.AbstractPropertyMapping.getCommonType(AbstractPropertyMapping.java:256)
at org.hibernate.persister.entity.AbstractPropertyMapping.addPropertyPath(AbstractPropertyMapping.java:221)
at org.hibernate.persister.entity.AbstractPropertyMapping.initPropertyPaths(AbstractPropertyMapping.java:330)
at org.hibernate.persister.entity.AbstractEntityPersister.initOrdinaryPropertyPaths(AbstractEntityPersister.java:2312)
at org.hibernate.persister.entity.AbstractEntityPersister.initPropertyPaths(AbstractEntityPersister.java:2359)
at org.hibernate.persister.entity.AbstractEntityPersister.postConstruct(AbstractEntityPersister.java:3918)
at org.hibernate.persister.entity.UnionSubclassEntityPersister.<init>(UnionSubclassEntityPersister.java:213)
at sun.reflect.GeneratedConstructorAccessor507.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:96)
... 44 more
I cannot provide you a test case. The error was produced from tests in a really huge application (>= 3M lines of code). I would need multiple days to isolate the problem.
The following exception is thrown with hibernate-core 5.2.14:
Caused by: java.lang.NullPointerException: null at org.hibernate.persister.entity.AbstractPropertyMapping.getSuperCollection(AbstractPropertyMapping.java:285) at org.hibernate.persister.entity.AbstractPropertyMapping.addPropertyPath(AbstractPropertyMapping.java:198) at org.hibernate.persister.entity.AbstractPropertyMapping.initPropertyPaths(AbstractPropertyMapping.java:395) at org.hibernate.persister.entity.AbstractEntityPersister.initOrdinaryPropertyPaths(AbstractEntityPersister.java:2300) at org.hibernate.persister.entity.AbstractEntityPersister.initPropertyPaths(AbstractEntityPersister.java:2347) at org.hibernate.persister.entity.AbstractEntityPersister.postConstruct(AbstractEntityPersister.java:3906) at org.hibernate.persister.entity.JoinedSubclassEntityPersister.<init>(JoinedSubclassEntityPersister.java:563)
The code in question looks like this:
AbstractPropertyMapping.java
private Collection getSuperCollection(MetadataImplementor metadata, PersistentClass clazz1, PersistentClass commonPersistentClass, String propertyName) { Class<?> c1 = clazz1.getMappedClass(); Class<?> c2 = commonPersistentClass.getMappedClass(); MappedSuperclass commonMappedSuperclass = null; // First we traverse up the clazz2/commonPersistentClass super types until we find a common type while ( !c2.isAssignableFrom( c1 ) ) { if ( commonPersistentClass == null) { /* L285 */ if ( commonMappedSuperclass.getSuperPersistentClass() == null ) { commonMappedSuperclass = commonMappedSuperclass.getSuperMappedSuperclass(); commonPersistentClass = null; } else { commonPersistentClass = commonMappedSuperclass.getSuperPersistentClass(); commonMappedSuperclass = null; } } else { if ( commonPersistentClass.getSuperclass() == null ) { commonMappedSuperclass = commonPersistentClass.getSuperMappedSuperclass(); commonPersistentClass = null; } else { commonPersistentClass = commonPersistentClass.getSuperclass(); commonMappedSuperclass = null; } } } // Then we traverse it's types up as long as possible until we find a type that has a collection binding while ( c2 != Object.class ) { if ( commonMappedSuperclass != null ) { Collection collection = metadata.getCollectionBinding( commonMappedSuperclass.getMappedClass().getName() + "." + propertyName ); if ( collection != null ) { return collection; } if ( commonMappedSuperclass.getSuperPersistentClass() == null ) { commonMappedSuperclass = commonMappedSuperclass.getSuperMappedSuperclass(); commonPersistentClass = null; } else { commonPersistentClass = commonMappedSuperclass.getSuperPersistentClass(); commonMappedSuperclass = null; } } else { Collection collection = metadata.getCollectionBinding( commonPersistentClass.getEntityName() + "." + propertyName ); if ( collection != null ) { return collection; } if ( commonPersistentClass.getSuperclass() == null ) { commonMappedSuperclass = commonPersistentClass.getSuperMappedSuperclass(); commonPersistentClass = null; } else { commonPersistentClass = commonPersistentClass.getSuperclass(); commonMappedSuperclass = null; } } } return null; }
/* L285 */
marks the line causing theNullPointerException
.Be aware that these two
while
loops would loop forever in absence of this exception since the variablesc1
andc2
are never reassigned and there are nobreak
statements either.