Child collection in tree structure is not resolved correctly, tries to include grandparents children

Description

Hi, I'm not entirely sure this is not a mistake on my side, but the following code:

@ManyToOne(fetch = FetchType.LAZY, optional = true) @JoinColumn(name = "parent_id") public T getParent() { return parent; } public void setParent(T parent) { this.parent = parent; } @OneToMany(mappedBy = "parent", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY) @OnDelete(action = OnDeleteAction.CASCADE) @OrderBy(value = "position") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public List<T> getChildren() { return children; }

produces

select children0_.parent_id as parent_12_0_1_, children0_.id as id1_0_1_, children0_.id as id1_0_0_, children0_.version as version2_0_0_, children0_.is_closed as is_close3_0_0_, children0_.parent_id as parent_12_0_0_, children0_.pos as pos4_0_0_, children0_.areaInterviewDetails_id as areaInt13_0_0_, children0_.beschreibung as beschrei5_0_0_, children0_.disabledWhenCharged as disabled6_0_0_, children0_.internalBreadCrumbDescription as internal7_0_0_, children0_.partOfInterview as partOfIn8_0_0_, children0_.kurzbeschreibung as kurzbesc9_0_0_, children0_.startOfInterview as startOf10_0_0_, children0_.startOfInterviewType as startOf11_0_0_, children0_.year_id as year_id14_0_0_ from Area children0_ where children0_.parent_id=2456 order by children0_.pos

in 5.2.17 and works fine. In 5.3.3 however, it's translated to

select children0_.parent_id as parent_12_0_1_, children0_.id as id1_0_1_, children0_.id as id1_0_0_, children0_.version as version2_0_0_, children0_.is_closed as is_close3_0_0_, children0_.parent_id as parent_12_0_0_, children0_.pos as pos4_0_0_, children0_.areaInterviewDetails_id as areaInt13_0_0_, children0_.beschreibung as beschrei5_0_0_, children0_.disabledWhenCharged as disabled6_0_0_, children0_.internalBreadCrumbDescription as internal7_0_0_, children0_.partOfInterview as partOfIn8_0_0_, children0_.kurzbeschreibung as kurzbesc9_0_0_, children0_.startOfInterview as startOf10_0_0_, children0_.startOfInterviewType as startOf11_0_0_, children0_.year_id as year_id14_0_0_ from Area children0_ where children0_.parent_id in (2456, 2349) order by children0_.pos

and tries include wrong items into the collection. 2349 ist the parent of 2456 and should not be included.

The error is:

15:30:10.359 [Thread-15] WARN org.hibernate.engine.loading.internal.LoadContexts | HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@4cfecc23<rs=Result set representing update count of 38> 15:30:10.361 [Thread-15] WARN o.h.engine.loading.internal.CollectionLoadContext | HHH000160: On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [1] entries 15:30:10.365 [Thread-15] ERROR d.gorillaconcept.onse.service.startup.OnseStartUpRunner | Cache init failed: java.lang.NullPointerException: null at org.hibernate.event.internal.DefaultLoadEventListener.getFromSharedCache(DefaultLoadEventListener.java:645) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.event.internal.DefaultLoadEventListener.loadFromSecondLevelCache(DefaultLoadEventListener.java:596) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:463) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:220) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:279) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:122) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:90) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1257) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:1140) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:682) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.type.EntityType.resolve(EntityType.java:464) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.type.ManyToOneType.resolve(ManyToOneType.java:239) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:172) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:129) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.performTwoPhaseLoad(AbstractRowReader.java:238) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:209) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:133) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:122) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.loadEntityBatch(AbstractLoadPlanBasedEntityLoader.java:145) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.loader.entity.plan.LegacyBatchingEntityLoaderBuilder$LegacyBatchingEntityLoader.load(LegacyBatchingEntityLoaderBuilder.java:107) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4265) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:509) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:479) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:220) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:279) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:122) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:90) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1257) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:1140) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:682) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.type.EntityType.resolve(EntityType.java:464) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.type.ManyToOneType.resolve(ManyToOneType.java:239) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:172) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:129) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1151) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.loader.Loader.processResultSet(Loader.java:1010) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.loader.Loader.doQuery(Loader.java:948) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:340) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:310) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.loader.Loader.loadCollection(Loader.java:2403) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.loader.collection.plan.LegacyBatchingCollectionInitializerBuilder$LegacyBatchingCollectionInitializer.initialize(LegacyBatchingCollectionInitializerBuilder.java:88) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:691) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:75) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:2246) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:571) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:253) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:567) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:138) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:277) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final] at de.gorillaconcept.onse.service.area.AreaService.recursiveAddChildren(AreaService.java:51) ~[de.gorillaconcept.onse-onse-core.jar:na]

Is this a bug, or maybe a fix and I can try a different configuration?

Thanks in advance and keep up the great work!

Activity

Show:

David Hansmann July 31, 2018 at 1:16 PM

Yes, thank you!

Guillaume Smet July 31, 2018 at 12:54 PM

I fixed the NPE as part of https://hibernate.atlassian.net/browse/HHH-12868 .

Do you agree that your original issue with the parent ids is a non-issue and we can close this one?

David Hansmann July 30, 2018 at 12:48 PM

Unfortunately I was not able to reproduce it by creating this in a test case.

David Hansmann July 30, 2018 at 12:48 PM

That was a very good tip. The bug had nothing to do with this collection, but seems to reside deeper down:

The Area object (which has getChildren) contains another Entity AreaInterviewDetails, which itself contains another Entity using an @OneToOne(cascade=CascadeType.ALL). This entity, named EmbeddedBlob is annotated with @Cache(usage = CacheConcurrencyStrategy.NONE) - as it should be, since the Blob contained is not cacheable anyway. If I change the annotation to@OneToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY) everything works fine.

So it seems like the CacheConcurrencyStrategy is not honored correctly when the entity is eager fetched Question Mark

Guillaume Smet July 30, 2018 at 10:19 AM
Edited

I suspect the collection loading is done this way because some batching is enabled. So it tries to load several elements at once. But it should affect them to the right collection after that so you shouldn't end up with incorrect objects in your collections. Look for hibernate.default_batch_fetch_size.

Do you really see invalid elements in your collection or was it a supposition?

As for the cache exception, are you using @Cache(usage = CacheConcurrencyStrategy.NONE) on this particular entity by any chance? I can reproduce the exception by using this particular option.

Note that using this option basically disables the cache.

I created https://hibernate.atlassian.net/browse/HHH-12868 to track the NPE issue. Still interested in a follow-up on the collection loading suspected issue.

Rejected

Details

Assignee

Reporter

Worked in

Components

Affects versions

Priority

Created July 27, 2018 at 1:31 PM
Updated July 31, 2018 at 3:04 PM
Resolved July 31, 2018 at 3:04 PM