Hibernate-reactive: Contoh gagal dengan ORM 5.4.24

Dibuat pada 20 Nov 2020  ·  37Komentar  ·  Sumber: hibernate/hibernate-reactive

Contoh salah satu log menggunakan org.hibernate:hibernate-core:5.5.0-SNAPSHOT:20201117.201048-196 :

Feersum Endjinn is a great book!
[ERROR] failed to execute statement [select author0_.id as id1_0_0_, author0_.name as name2_0_0_ from authors author0_ where author0_.id in (?,?)]
[ERROR] could not load an entity batch: [org.hibernate.example.reactive.Author#<1, 3>]
java.util.concurrent.CompletionException: org.hibernate.LazyInitializationException: Collection cannot be initialized: org.hibernate.example.reactive.Author.books
    at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:273) ~[?:1.8.0_275]
    at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:280) ~[?:1.8.0_275]
    at java.util.concurrent.CompletableFuture.uniAccept(CompletableFuture.java:673) ~[?:1.8.0_275]
    at java.util.concurrent.CompletableFuture.uniAcceptStage(CompletableFuture.java:683) ~[?:1.8.0_275]
    at java.util.concurrent.CompletableFuture.thenAccept(CompletableFuture.java:2010) ~[?:1.8.0_275]
    at java.util.concurrent.CompletableFuture.thenAccept(CompletableFuture.java:110) ~[?:1.8.0_275]
    at org.hibernate.reactive.loader.ReactiveLoaderBasedResultSetProcessor.reactiveInitializeEntitiesAndCollections(ReactiveLoaderBasedResultSetProcessor.java:150) ~[hibernate-reactive-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
    at org.hibernate.reactive.loader.ReactiveLoaderBasedResultSetProcessor.reactiveExtractResults(ReactiveLoaderBasedResultSetProcessor.java:83) ~[hibernate-reactive-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
Error: Exception in thread "main" java.util.concurrent.CompletionException: org.hibernate.LazyInitializationException: Collection cannot be initialized: org.hibernate.example.reactive.Author.books
    at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:273)
    at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:280)
    at org.hibernate.reactive.loader.ReactiveLoader.reactiveProcessResultSet(ReactiveLoader.java:123) ~[hibernate-reactive-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
    at org.hibernate.reactive.loader.ReactiveLoader.lambda$doReactiveQueryAndInitializeNonLazyCollections$0(ReactiveLoader.java:71) ~[hibernate-reactive-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
    at java.util.concurrent.CompletableFuture.uniCompose(CompletableFuture.java:966) ~[?:1.8.0_275]
    at java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:940) ~[?:1.8.0_275]
    at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:488) ~[?:1.8.0_275]
    at java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:1975) ~[?:1.8.0_275]

...

Caused by: org.hibernate.LazyInitializationException: Collection cannot be initialized: org.hibernate.example.reactive.Author.books
    at org.hibernate.reactive.session.impl.ReactiveSessionImpl.initializeCollection(ReactiveSessionImpl.java:320)
    at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:589)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:264)
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:585)
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:149)
bug

Semua 37 komentar

Goops, Anda benar: @Sanne dan saya sama-sama melewatkan ini karena kegagalan palsu lainnya di CI.

Saya berani menebak bahwa ini terkait dengan #443.

Apakah masalah itu terkait dengan DirtyChecking?
Saya pikir masalah itu terkait dengan ini: https://github.com/hibernate/hibernate-reactive/issues/447

Bagaimanapun, itu terjadi setelah pembaruan ke ORM 5.4.24

Apakah masalah itu terkait dengan DirtyChecking?

Yah, saya pikir bug itu terkait dengan pemuatan batch. Saya mungkin salah sekalipun.

Apakah masalah itu terkait dengan DirtyChecking?

Yah, saya pikir bug itu terkait dengan pemuatan batch. Saya mungkin salah sekalipun.

Oh well, sepertinya saya salah dan masalahnya memang di tempat lain.

Saya sedang mengerjakan kasus uji. Mudah-mudahan saya akan dapat mengkonfirmasi ini segera.

Masuk akal karena hanya contoh yang gagal dan itu adalah satu-satunya tempat di mana kami mengaktifkan peningkatan bytecode

OK bagus.

Jadi iya. Masalahnya adalah pemeriksaan kotor koleksi ketika peningkatan kode byte diaktifkan. Saya tidak tahu mengapa itu bekerja sebelumnya. Mungkin, bug di ORM ini menyembunyikan masalah dan sekarang setelah diperbaiki, kami melihatnya.

Uff, apa PITA.

OTOH, mengapa koleksi memeriksa bahkan _matter_ ketika kita bahkan belum memiliki CollectionPersister ?

Ini adalah masalah:

Metode yang disempurnakan $$_hibernate_hasDirtyAttributes telah berubah, dari

    public boolean $$_hibernate_hasDirtyAttributes() {
        boolean var1 = false;
        var1 = this.$$_hibernate_tracker != null && !this.$$_hibernate_tracker.isEmpty();
        return var1;
    }

ke

    public boolean $$_hibernate_hasDirtyAttributes() {
        boolean var1 = false;
        var1 = this.$$_hibernate_tracker != null && !this.$$_hibernate_tracker.isEmpty() || this.$$_hibernate_areCollectionFieldsDirty();
        return var1;
    }

    public boolean $$_hibernate_areCollectionFieldsDirty() {
        boolean var1 = false;
        if (!var1 && this.$$_hibernate_collectionTracker != null) {
            if (this.movies == null && this.$$_hibernate_collectionTracker.getSize("movies") != -1) {
                var1 = true;
            } else if (this.movies != null && this.$$_hibernate_collectionTracker.getSize("movies") != this.movies.size()) {
                var1 = true;
            }
        }

        return var1;
    }

panggilan ke this.movies.size() menyebabkan LazyInitializationException

movies adalah nama asosiasi di dalam tes yang saya buat

@DavideD jadi menurut Anda apa yang terjadi di sini hanya karena kita tidak memiliki init malas transparan (yaitu tidak ada panggilan ke fetch() ), atau apakah itu sesuatu yang lebih dalam?

@DavideD Saya telah mengomentari https://github.com/hibernate/hibernate-orm/pull/3645 , karena panggilan ke size() itu tidak cocok untuk saya. (Tapi saya bisa dengan mudah melewatkan sesuatu.)

@DavideD jadi menurut Anda apa yang terjadi di sini hanya karena kita tidak memiliki init malas transparan (yaitu tidak ada panggilan untuk mengambil()), atau apakah itu sesuatu yang lebih dalam?

Saya pikir itu masalahnya. Saya mencoba melihat apakah saya dapat mengambil koleksi di suatu tempat sehingga sudah diambil.
Omong-omong, semuanya berfungsi jika saya mengatur asosiasi untuk pengambilan EAGER.

Saya mencoba melihat apakah saya dapat mengambil koleksi di suatu tempat sehingga sudah diambil.

Oke, tapi jangan bunuh diri pada _sekarang_ itu karena masih terasa salah bagi saya bahwa kami mengambil asosiasi yang tidak diambil dengan mappedBy hanya untuk memeriksa elemennya secara kotor. Mari kita lihat apa yang @beikov dan @Sanne katakan.

(OTOH, bahkan jika inti tidak melakukan hal yang benar _dalam kasus khusus ini_, kami mungkin masih memerlukan perbaikan yang Anda kerjakan dalam kasus lain.)

Terima kasih @gavinking

Mengapa koleksi film != null ? Saya mencoba mereproduksi ini dalam inti, tetapi tidak bisa karena koleksi seperti itu tidak boleh non-null jika malas.

Yah saya ingat bahwa ada diskusi yang agak panjang di suatu tempat. Masalah yang saya buka di mana saya berpendapat bahwa "kemalasan ganda" atau koleksi ini setidaknya bisa dibilang buruk di Hibernate ORM, dan masalah yang jauh lebih buruk untuk HR, di mana pengambilan tidak transparan. Kami perlu membiarkan Anda mendapatkan referensi ke koleksi untuk memanggil fetch() di atasnya.

Oke menemukannya. Jadi, mungkinkah ini terkait dengan #374?

Apakah collectionsInDefaultFetchGroupEnabled selalu benar di RX?

Hmm, jika saya menyetelnya ke true, koleksinya diinisialisasi dengan penuh semangat.

Apakah collectionsInDefaultFetchGroupEnabled selalu benar di RX?

Ya, itu.

Hmm, jika saya menyetelnya ke true, koleksinya diinisialisasi dengan penuh semangat.

Ummm... benarkah? Itu bukan niatnya!

collectionsInDefaultFetchGroupEnabled seharusnya hanya menyertakan proxy koleksi di grup pengambilan default. Itu tidak seharusnya mengambil koleksi itu sendiri.

Jadi entah saya benar-benar kacau, atau sesuatu telah berubah sejak saya menulis kode itu.

Saya setuju dengan Anda bahwa pendekatan peningkatan saat ini tidak ideal dan bahwa bidang tersebut harus diinisialisasi ke koleksi persisten, tetapi saya pikir masalah yang Anda alami di RX mungkin disebabkan oleh hal lain. Ketika saya menyetel bendera ke true, saya melihat koleksi diinisialisasi melalui jejak ini:

org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:585)
org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:149)
org.hibernate.collection.internal.AbstractPersistentCollection$1.doWork(AbstractPersistentCollection.java:178)
org.hibernate.collection.internal.AbstractPersistentCollection$1.doWork(AbstractPersistentCollection.java:163)
org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:264)
org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:162)
org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:371)
org.hibernate.test.bytecode.enhancement.dirty.DirtyTrackingCollectionTest$StringsEntity.$$_hibernate_removeDirtyFields(DirtyTrackingCollectionTest.java)
org.hibernate.test.bytecode.enhancement.dirty.DirtyTrackingCollectionTest$StringsEntity.$$_hibernate_clearDirtyCollectionNames(DirtyTrackingCollectionTest.java)
org.hibernate.test.bytecode.enhancement.dirty.DirtyTrackingCollectionTest$StringsEntity.$$_hibernate_clearDirtyAttributes(DirtyTrackingCollectionTest.java)
org.hibernate.tuple.entity.PojoEntityTuplizer.afterInitialize(PojoEntityTuplizer.java:228)
org.hibernate.persister.entity.AbstractEntityPersister.afterInitialize(AbstractEntityPersister.java:5093)
org.hibernate.engine.internal.TwoPhaseLoad.afterInitialize(TwoPhaseLoad.java:405)
org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.afterInitialize(AbstractRowReader.java:271)
org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:214)
org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:96)
org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:105)
org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:285)
org.hibernate.persister.entity.AbstractEntityPersister.doLoad(AbstractEntityPersister.java:4441)
org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4431)
org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:569)
org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:537)
org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:208)
org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:332)
org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:108)
org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:74)
org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:121)
org.hibernate.internal.SessionImpl.fireLoadNoChecks(SessionImpl.java:1186)
org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1175)
org.hibernate.internal.SessionImpl.access$2100(SessionImpl.java:193)
org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.doLoad(SessionImpl.java:2786)
org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.lambda$load$1(SessionImpl.java:2767)
org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.perform(SessionImpl.java:2723)
org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2767)
org.hibernate.internal.SessionImpl.find(SessionImpl.java:3322)
org.hibernate.internal.SessionImpl.find(SessionImpl.java:3284)
org.hibernate.test.bytecode.enhancement.dirty.DirtyTrackingCollectionTest.lambda$test$1(DirtyTrackingCollectionTest.java:57)
org.hibernate.testing.transaction.TransactionUtil.doInJPA(TransactionUtil.java:235)
org.hibernate.testing.transaction.TransactionUtil.doInJPA(TransactionUtil.java:276)
org.hibernate.test.bytecode.enhancement.dirty.DirtyTrackingCollectionTest.test(DirtyTrackingCollectionTest.java:56)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
org.hibernate.testing.junit4.ExtendedFrameworkMethod.invokeExplosively(ExtendedFrameworkMethod.java:45)
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:298)
org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:292)
java.util.concurrent.FutureTask.run(FutureTask.java:266)
java.lang.Thread.run(Thread.java:748)

Jadi $$_hibernate_removeDirtyFields() memanggil size() pada koleksi yang tidak diinisialisasi. _Harus_ begitu?

Saya setuju dengan Anda bahwa pendekatan peningkatan saat ini tidak ideal dan bahwa bidang tersebut harus diinisialisasi ke koleksi persisten, tetapi saya pikir masalah yang Anda alami di RX mungkin disebabkan oleh hal lain. Ketika saya menyetel bendera ke true, saya melihat koleksi diinisialisasi melalui jejak ini:

Saya mungkin melewatkan sesuatu, tetapi bukankah ini masalah yang sama?
Itu masih memanggil size() tetapi dari metode yang berbeda

Kamu benar. Rupanya koleksi tidak terdaftar sebagai malas yang menyebabkan masalah ini. Aku sedang menyelidiki sekarang.

Di sini PR yang harus memperbaiki masalah ini: https://github.com/hibernate/hibernate-orm/pull/3664

Terima kasih @beikov , tes tampaknya berhasil menggunakan cabang itu

@beikov luar biasa, terima kasih

Terima kasih @beikov , tes tampaknya berhasil menggunakan cabang itu

@DavideD dapatkah Anda menguji ulang sekarang, @beikov baru saja memperbarui PR, mari kita lihat apakah itu masih memperbaiki masalah.

Di sini PR yang harus memperbaiki masalah ini: hibernate/hibernate-orm#3664

Dikonfirmasi, kita hanya perlu rilis hibernate-core .

Diperbaiki oleh #463

Terima kasih semuanya

Apakah halaman ini membantu?
0 / 5 - 0 peringkat