Child collection in tree structure is not resolved correctly, tries to include grandparents children
Description
Activity
David Hansmann July 31, 2018 at 1:16 PM
Yes, thank you!
Guillaume Smet July 31, 2018 at 12:54 PM
@David Hansmann 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
Guillaume Smet July 30, 2018 at 10:19 AMEdited
@David Hansmann 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.
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!