Using JPA objects in parallel streams with Spring

梦想的初衷 提交于 2019-12-12 05:16:34

问题


I'm working on spring-boot application with JPA. In the code I found a really suspicious part which does something like (simplified example, the code otherwise contains a lot of clutter):

entityRepository.findAll().parallel() // The findAll returns already a stream, it's a CrudRepository from Spring
   .filter (...)
   .map(e -> {
      OtherDbObject other = service.getOtherDbObjectBasedOn(e);
      boolean hasSomething = other.getProperties().stream() //properties is fetch type EAGER @OneToMany collection in OtherDbObject
        .filter(...)
        .findFirst()
        .isPresent();

      ...
   })

It seems the parallel is causing whole lot of troubles including errors like:

jvm 1    | org.hibernate.AssertionFailure: bug adding collection twice
jvm 1    |      at org.hibernate.engine.internal.StatefulPersistenceContext.addCollection(StatefulPersistenceContext.java:857)
jvm 1    |      at org.hibernate.engine.internal.StatefulPersistenceContext.addInitializedCollection(StatefulPersistenceContext.java:896)
jvm 1    |      at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:242)
jvm 1    |      at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:221)
jvm 1    |      at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:194)
jvm 1    |      at org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerImpl.endLoading(CollectionReferenceInitializerImpl.java:154)
jvm 1    |      at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishLoadingCollections(AbstractRowReader.java:249)
jvm 1    |      at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:212)
jvm 1    |      at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:133)
jvm 1    |      at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:122)
jvm 1    |      at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86)
jvm 1    |      at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:88)
jvm 1    |      at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:688)
jvm 1    |      at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:75)
jvm 1    |      at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1991)
jvm 1    |      at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:570)
jvm 1    |      at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:252)
jvm 1    |      at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:566)
jvm 1    |      at org.hibernate.collection.internal.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:739)
jvm 1    |      at org.hibernate.engine.internal.StatefulPersistenceContext.initializeNonLazyCollections(StatefulPersistenceContext.java:924)
jvm 1    |      at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:149)
jvm 1    |      at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86)
jvm 1    |      at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:88)
jvm 1    |      at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:688)
jvm 1    |      at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:75)
jvm 1    |      at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1991)
jvm 1    |      at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:570)
jvm 1    |      at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:252)
jvm 1    |      at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:566)
jvm 1    |      at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:135)
jvm 1    |      at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:277)
jvm 1    |      at java.util.Spliterators$IteratorSpliterator.estimateSize(Spliterators.java:1821)
jvm 1    |      at java.util.Spliterator.getExactSizeIfKnown(Spliterator.java:408)
jvm 1    |      at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:497)
jvm 1    |      at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
jvm 1    |      at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
jvm 1    |      at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
jvm 1    |      at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
jvm 1    |      at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464)
...

I would say it's at least suspicious to do something DB related in parallel stream but I can't any evidence that it should be avoided.

I would appreciate any help in either explaining the error or finding solid evidence which proves that parallel streams with JPA inside are unsafe.

来源:https://stackoverflow.com/questions/44029856/using-jpa-objects-in-parallel-streams-with-spring

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!