Quarkus์์ Mutiny์์ ์ฐ๊ฒฐ์ ๋๋ฆฌ๊ฒ ๊ฐ์ ธ์ค๋ ค๊ณ ํ ๋ ๋ฐ์ดํฐ๋ฅผ ์ ์งํ๋ ๋ฐ ์ฌ์ฉ๋ ์ธ์ ๊ณผ ๋ค๋ฅธ ์ธ์ ์์ ๊ฐ์ ธ์ค๊ธฐ๊ฐ ์ํ๋๋ฉด ์๋ํ์ง ์์ต๋๋ค. ๋์ผํ ์ธ์ ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ(๋ฐ๋ผ์ ๋์ผํ ์ธ์ ์์ ์ ์งํ ์งํ ๊ฐ์ ธ์ค๊ธฐ) ์๋ํฉ๋๋ค.
์์๋๋ ํ๋
๋ค๋ฅธ ์ธ์
์์๋ ์๋ํฉ๋๋ค.
์ค์ ํ๋
์ฐ๊ฒฐ์ ๊ฐ์ ธ์ค๋ ค๊ณ ํ ๋ ์์ธ๊ฐ ๋ฐ์ํฉ๋๋ค.
2021-03-12 09:56:23,634 ERROR [org.jbo.res.rea.com.cor.AbstractResteasyReactiveContext] (vert.x-eventloop-thread-2) Request failed: org.hibernate.LazyInitializationException: Collection cannot be initialized: com.example.Author.books
at org.hibernate.reactive.session.impl.ReactiveSessionImpl.initializeCollection(ReactiveSessionImpl.java:330)
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)
at org.hibernate.collection.internal.AbstractPersistentCollection$1.doWork(AbstractPersistentCollection.java:178)
at org.hibernate.collection.internal.AbstractPersistentCollection$1.doWork(AbstractPersistentCollection.java:163)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:264)
at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:162)
at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:371)
at org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor.takeCollectionSizeSnapshot(LazyAttributeLoadingInterceptor.java:160)
at org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor.lambda$loadAttribute$0(LazyAttributeLoadingInterceptor.java:110)
at org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper.performWork(EnhancementHelper.java:130)
at org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor.loadAttribute(LazyAttributeLoadingInterceptor.java:76)
at org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor.fetchAttribute(LazyAttributeLoadingInterceptor.java:72)
at org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor.handleRead(LazyAttributeLoadingInterceptor.java:53)
at org.hibernate.bytecode.enhance.spi.interceptor.AbstractInterceptor.readObject(AbstractInterceptor.java:153)
at com.example.Author.$$_hibernate_read_books(Author.java)
at com.example.Author.getBooks(Author.java:43)
at com.example.TestResource.lambda$getBooks$2(TestResource.java:61)
at io.smallrye.mutiny.operators.UniOnItemTransformToUni.invokeAndSubstitute(UniOnItemTransformToUni.java:31)
at io.smallrye.mutiny.operators.UniOnItemTransformToUni$2.onItem(UniOnItemTransformToUni.java:74)
at io.smallrye.mutiny.context.ContextPropagationUniInterceptor$1.lambda$onItem$1(ContextPropagationUniInterceptor.java:31)
at io.smallrye.context.impl.wrappers.SlowContextualExecutor.execute(SlowContextualExecutor.java:19)
at io.smallrye.mutiny.context.ContextPropagationUniInterceptor$1.onItem(ContextPropagationUniInterceptor.java:31)
at io.smallrye.mutiny.operators.UniSerializedSubscriber.onItem(UniSerializedSubscriber.java:85)
at io.smallrye.mutiny.context.ContextPropagationUniInterceptor$1.lambda$onItem$1(ContextPropagationUniInterceptor.java:31)
at io.smallrye.context.impl.wrappers.SlowContextualExecutor.execute(SlowContextualExecutor.java:19)
at io.smallrye.mutiny.context.ContextPropagationUniInterceptor$1.onItem(ContextPropagationUniInterceptor.java:31)
at io.smallrye.mutiny.operators.UniDelegatingSubscriber.onItem(UniDelegatingSubscriber.java:24)
at io.smallrye.mutiny.context.ContextPropagationUniInterceptor$1.lambda$onItem$1(ContextPropagationUniInterceptor.java:31)
at io.smallrye.context.impl.wrappers.SlowContextualExecutor.execute(SlowContextualExecutor.java:19)
at io.smallrye.mutiny.context.ContextPropagationUniInterceptor$1.onItem(ContextPropagationUniInterceptor.java:31)
at io.smallrye.mutiny.operators.UniSerializedSubscriber.onItem(UniSerializedSubscriber.java:85)
at io.smallrye.mutiny.context.ContextPropagationUniInterceptor$1.lambda$onItem$1(ContextPropagationUniInterceptor.java:31)
at io.smallrye.context.impl.wrappers.SlowContextualExecutor.execute(SlowContextualExecutor.java:19)
at io.smallrye.mutiny.context.ContextPropagationUniInterceptor$1.onItem(ContextPropagationUniInterceptor.java:31)
at io.smallrye.mutiny.operators.uni.builders.UniCreateFromCompletionStage.lambda$forwardFromCompletionStage$1(UniCreateFromCompletionStage.java:30)
at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:859)
at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:837)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2073)
at com.ibm.asyncutil.iteration.AsyncTrampoline$TrampolineInternal.unroll(AsyncTrampoline.java:127)
at com.ibm.asyncutil.iteration.AsyncTrampoline$TrampolineInternal.lambda$unroll$0(AsyncTrampoline.java:123)
at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:859)
at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:837)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2073)
at org.hibernate.reactive.pool.impl.Handlers.lambda$toCompletionStage$0(Handlers.java:26)
at io.vertx.sqlclient.impl.SqlResultHandler.complete(SqlResultHandler.java:98)
at io.vertx.sqlclient.impl.SqlResultHandler.handle(SqlResultHandler.java:87)
at io.vertx.sqlclient.impl.SqlResultHandler.handle(SqlResultHandler.java:33)
at io.vertx.sqlclient.impl.SocketConnectionBase.handleMessage(SocketConnectionBase.java:241)
at io.vertx.sqlclient.impl.SocketConnectionBase.lambda$init$0(SocketConnectionBase.java:88)
at io.vertx.core.net.impl.NetSocketImpl.lambda$new$2(NetSocketImpl.java:101)
at io.vertx.core.streams.impl.InboundBuffer.handleEvent(InboundBuffer.java:237)
at io.vertx.core.streams.impl.InboundBuffer.write(InboundBuffer.java:127)
at io.vertx.core.net.impl.NetSocketImpl.handleMessage(NetSocketImpl.java:357)
at io.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:366)
at io.vertx.core.impl.EventLoopContext.execute(EventLoopContext.java:43)
at io.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:229)
at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:163)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
at io.vertx.pgclient.impl.codec.PgEncoder.lambda$write$0(PgEncoder.java:78)
at io.vertx.pgclient.impl.codec.PgCommandCodec.handleReadyForQuery(PgCommandCodec.java:138)
at io.vertx.pgclient.impl.codec.PgDecoder.decodeReadyForQuery(PgDecoder.java:226)
at io.vertx.pgclient.impl.codec.PgDecoder.channelRead(PgDecoder.java:86)
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
์ฌ์๊ธฐ
https://github.com/markusdlugi/hibernate-reactive-lazy-fetching
๋์์ ์ฌํํ๋ ๋จ๊ณ:
infrastructure/docker-compose.yml
์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์์ํฉ๋๋ค.mvn quarkus:dev
์ฌ์ฉํ์ฌ Quarkus ์ ํ๋ฆฌ์ผ์ด์
์์POST http://localhost:8080/test/working
.GET http://localhost:8080/test/failing/1
(๋๋ POST http://localhost:8080/test/failing
๋ฅผ ํตํด ์์ฑ๋ ๋ค๋ฅธ ์์ฑ์ ID)./cc @DavidD @gavinking
์, ์ฐ๋ฆฌ๋ ์ด๊ฒ์ด ์ฌ๋ฐ๋ฅธ ์ผ์ด๋ผ๊ณ ๊ฒฐ์ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. JPA์๋ ์ํฐํฐ ์ธ์คํด์ค๋ฅผ ์ธ์
๊ณผ ๋ค์ ์ฐ๊ฒฐํ๋ค๋ ๊ฐ๋
์ด ์์ต๋๋ค. ๊ทธ๊ฒ์ saveOrUpdate()
๋ฅผ ์ฌ์ฉํ์ฌ ๋ถ๋ฆฌ๋ ๊ฐ์ฒด๋ฅผ ์ง์ ์ฌ์ฐ๊ฒฐํ ์ ์๋ Hibernate์ ์ ๋ง ์ค๋๋ ์ฌ์ฉ ํจํด๊ณผ ์ฝ๊ฐ ๋ค๋ฆ
๋๋ค. JPA์์ ๋ถ๋ฆฌ๋ ๊ฐ์ฒด๋ฅผ ์ฒ๋ฆฌํ๋ ๋ชจ๋ธ์ merge()
์์
์
๋๋ค.
(๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ ์ฌ์ฉํ์ง ์๋ ๋ฐ๋ ์ข์ ์ด์ ๊ฐ ์์ต๋๋ค. ๊ฒฝํ์ ์ค์ ๋ก ์ฌ์ฉ์๋ ์ฌ๊ฒฐํฉ์ผ๋ก ์ธํด ํผ๋์ ๋น ์ง๊ฒ ๋ฉ๋๋ค.)
๋ถ๋ฆฌ๋ ์ปฌ๋ ์ ์ ๋ก๋ํ๋ ๊ฒ์ ์ค์ ๋ก ๋ถ๋ชจ๋ฅผ ๋ค์ ์ฐ๊ฒฐํ๋ ๊ฒ์ ์๋ฏธํ๋ฏ๋ก ๋จ์ํ ์ง์ํ์ง ์์ต๋๋ค.
๊ทธ๋ฌ๋ IIRC์์๋ StatelessSession
ํ๋ก๊ทธ๋๋ฐ ๋ชจ๋ธ๊ณผ ํจ์ฌ ๋ ํธํ๋๊ธฐ ๋๋ฌธ์ ์ด ์์
์ ํ ์ ์์ต๋๋ค. ์ํ ๋น์ ์ฅ ์ธ์
์ ์ฌ์ฉํด ๋ณด๊ณ ํจ๊ณผ๊ฐ ์๋์ง ์๋ ค์ฃผ์ญ์์ค.
@gavinking๋ , ๋น ๋ฅธ ๋ต๋ณ ๊ฐ์ฌํฉ๋๋ค.
๋ง์ํ์ ๋ด์ฉ์ ์ดํดํ๊ณ ์๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ๊ทธ๋์ ๋ด๊ฐ ๊ตฌํํ ๊ฒ์ ๋ฌธ์์ ์ค๋ช ๋ ๊ฒ๊ณผ ์ ํํ ๊ฐ์ต๋๋ค.
session.find(Author.class, authorId)
.chain(author -> Mutiny.fetch(author.getBooks()));
์ด๊ฒ์ ์ ์์ ๊ทธ์ ์ฑ ์ด ๋์ผํ ์ธ์ (์ฆ, ๋์ผํ HTTP ์์ฒญ์์)์ผ๋ก ์ง์๋ ๊ฒฝ์ฐ ์๋ํ์ง๋ง ๋ค๋ฅธ ์ธ์ (์ฆ, ๋ค๋ฅธ ์์ฒญ)์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์๋ํ์ง ์์ต๋๋ค.
๊ทธ๋์ ์ด๊ฒ์ด ์ ์ด๋ "์ ์์ ์ธ"(์ํ ์ ์ฅ?) ์ธ์
์ ๋ํด ์๋๋ ๋์์ด๋ผ๋ ๊ฒ์ ์๋ฏธํฉ๋๊น? ์ด๊ฒ์ ๋ด๊ฐ ๊ฑฐ์ ํญ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ ์งํ ํ ์ผ์ ์๊ฐ์ด ์ง๋๋ฉด ๋ค๋ฅธ ์ธ์
์์ ์ผ๋ถ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ค๊ณ ์๋ํ๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ์ ๋ง ํ์ค์ ์ธ ์ฌ์ฉ ์ฌ๋ก์ฒ๋ผ ๋ณด์
๋๋ค. ์ด๋ ์ผ๋ฐ ์ธ์
์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์ง์ฐ ์ฐ๊ฒฐ์ด ์ง์๋์ง ์์์ ์๋ฏธํฉ๋๋ค. ์ด ๊ฒฝ์ฐ ๋ฌธ์์์ ์ง์ฐ ์ฐ๊ฒฐ์ ๊ฐ์ ธ์ค๋ ค๋ฉด StatelessSession
์ฌ์ฉํด์ผ ํ๋ค๊ณ ๋ช
์์ ์ผ๋ก ์ธ๊ธํด์ผ ํ๋ค๊ณ ์ฃผ์ฅํฉ๋๋ค.
์ ์ธ์
์์ getReference()
๋ฅผ ์ฌ์ฉํ์ฌ ์ปฌ๋ ์
์ ์์ ํ ์ํฐํฐ์ ๋ํ ์ธ์
๋ฐ์ธ๋ฉ ์ฐธ์กฐ๋ฅผ ๊ฐ์ ธ์์ผ ํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ํ๋ ๋๋ก ์ปฌ๋ ์
์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
์ด๊ฒ์ ํ์ค JPA ๋ชจ๋ธ์ด๋ฉฐ getReference()
์ค๋ฒ๋ก๋ํ๊ธฐ ๋๋ฌธ์ HR์์ ์ฌ์ฉํ๊ธฐ๊ฐ ํจ์ฌ ๋ ์ฝ์ต๋๋ค.
@gavinking ์ด๋ฐ ๋ป์ธ๊ฐ์?
Author reference = session.getReference( Author.class, authorId );
return Mutiny.fetch( reference.getBooks() );
๋น์ฐํ์ง๋ง ์ ๋ ๋ ์ฝ๊ฒ ๋ง๋ค์์ต๋๋ค. ๋ถ๋ฆฌ๋ ์์ฑ์๋ฅผ getReference()
์ง์ ์ ๋ฌํ ์ ์์ต๋๋ค.
์ข์, ๋๋ ๊ทธ ์ ์๋ค์ ์๋ํ์ง๋ง ๋ถํํ๋ ๊ทธ๊ฒ๋ค๋ ์๋ํ์ง ์์๋ค. ๋ด๊ฐ ์ฌ๊ธฐ์์ ๋ญ๊ฐ ์๋ชปํ๊ณ ์๋ค๋ฉด ์น์ ํ๊ฒ ์ง์ ํด ์ฃผ์ค ์ ์์ต๋๋ค.
getReference()
์ฌ์ฉํ๋ ์ ๊ทผ ๋ฐฉ์์ ๋ค์ ์์ธ์ ํจ๊ป ์คํจํฉ๋๋ค.
2021-03-12 14:17:51,381 ERROR [org.jbo.res.rea.ser.cor.ExceptionMapping] (vert.x-eventloop-thread-10) Request failed : java.lang.NullPointerException
at org.hibernate.engine.internal.AbstractEntityEntry.overwriteLoadedStateCollectionValue(AbstractEntityEntry.java:336)
at org.hibernate.persister.entity.AbstractEntityPersister.initializeLazyProperty(AbstractEntityPersister.java:1144)
at org.hibernate.persister.entity.AbstractEntityPersister.initializeEnhancedEntityUsedAsProxy(AbstractEntityPersister.java:4497)
at org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor.forceInitialize(EnhancementAsProxyLazinessInterceptor.java:221)
at org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor.lambda$handleRead$0(EnhancementAsProxyLazinessInterceptor.java:133)
at org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper.performWork(EnhancementHelper.java:130)
at org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor.handleRead(EnhancementAsProxyLazinessInterceptor.java:98)
at org.hibernate.bytecode.enhance.spi.interceptor.AbstractInterceptor.readObject(AbstractInterceptor.java:153)
at com.example.Author.$$_hibernate_read_books(Author.java)
at com.example.Author.getBooks(Author.java:43)
at com.example.TestResource.getBooksUsingReference(TestResource.java:69)
...
StatelessSession
์ฌ์ฉํ๋ ๋ค๋ฅธ ์ ์๋ ์๋ฃจ์
์ ๋ค์๊ณผ ํจ๊ป ์คํจํฉ๋๋ค.
2021-03-12 14:21:11,840 ERROR [org.jbo.res.rea.ser.cor.ExceptionMapping] (vert.x-eventloop-thread-5) Request failed : org.hibernate.LazyInitializationException: Unable to perform requested lazy initialization [com.example.Author.books] - no session and settings disallow loading outside the Session
at org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper.throwLazyInitializationException(EnhancementHelper.java:199)
at org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper.performWork(EnhancementHelper.java:89)
at org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor.loadAttribute(LazyAttributeLoadingInterceptor.java:76)
at org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor.fetchAttribute(LazyAttributeLoadingInterceptor.java:72)
at org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor.handleRead(LazyAttributeLoadingInterceptor.java:53)
at org.hibernate.bytecode.enhance.spi.interceptor.AbstractInterceptor.readObject(AbstractInterceptor.java:153)
at com.example.Author.$$_hibernate_read_books(Author.java)
at com.example.Author.getBooks(Author.java:43)
at com.example.TestResource.lambda$getBooksUsingStatelessSession$3(TestResource.java:78)
...
์ดํด๋ณด๊ฒ ์ต๋๋ค. ๋ฐ์ดํธ์ฝ๋ ํฅ์๊ณผ ๊ด๋ จ์ด ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
@DavidD , ์ ๋ฐ์ดํธ๊ฐ ์์ต๋๊น?
์ด repo์์ session-example
๋ฅผ ์ฌ์ฉํ์ฌ Quarkus ์์ด ๋ฌธ์ ๋ฅผ ์ฌํํ๋ ค๊ณ ํ์ง๋ง ๊ทธ๋ ๊ฒ ํ ์ ์์์ต๋๋ค. Hibernate Reactive์ ์ผ๋ฐ Mutiny๋ง ์์ผ๋ฉด ์์๋๋ก ์๋ํฉ๋๋ค. ๋ํ find()
, getReference()
๋๋ StatelessSession
ํ์ ์์ด ์๋ํฉ๋๋ค.
๋ฐ๋ผ์ ์ด ๋ฌธ์ ๋ Quarkus์์๋ง ๋ฐ์ํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
์์ง ์กฐ์ฌ ์ค์ ๋๋ค.
Quarkus์์ ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฑํ๋ ๋ฐ์ดํธ์ฝ๋ ํฅ์ ๋๋ฌธ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค.
Hibernate Reactive๋ง ์ฌ์ฉํ ๋ ์ด๋ค ์์ฑ ์งํฉ์ด ๋ฌธ์ ๋ฅผ ์ฌํํ๋์ง ์์ง ํ์
ํ์ง ๋ชปํ์ต๋๋ค. ๊ทธ๋ฌ๋ ๋๋ ์ค๋๋ ๊ณ์ ์ผํ ๊ฒ์ด๋ค
์ด์ ๋ฐ์ํ์์ ์ค๋ฅ๋ฅผ ์ฌํํ ์ ์์ต๋๋ค. ๋ ๊ฐ์ง๊ฐ ํ์ํฉ๋๋ค.
hibernate.bytecode.allow_enhancement_as_proxy
๋ฅผ true๋ก ์ค์ SessionFactoryOptions#enableCollectionInDefaultFetchGroup
๋ฅผ false๋ก ์ค์ ํฉ๋๋ค. true๋ก ์ค์ ํด์ผํฉ๋๋ค https://github.com/hibernate/hibernate-reactive/blob/a3f4c61eef71baab8ca321da5af0bfb9052bde4b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/provider/service/ReactiveSessionFactoryBuilderService.java #L27@gavinking Quarkus์์ enableCollectionInDefaultFetchGroup
๊ฐ false๋ก ์ค์ ๋์ด ์๋์ง ํ์ธํด์ผ ํ๋ค๊ณ ์๊ฐํ๋ ๊ฒ์ด ๋ง์ต๋๊น? ๋๋ ํ์ฌ ์ ์ฒด ๋ฌธ์ ๋ฅผ ์์ ํ ์ดํดํ์ง ๋ชปํ๋ค๋ ๊ฒ์ ์ธ์ ํฉ๋๋ค(๋๋ ๋ฌธ์ #374์ ๋ํ ๋ํ๋ฅผ ๋ฐ๋ฅด๋ ค๊ณ ๋
ธ๋ ฅํ์ต๋๋ค)
์. ๊ธฐ๋ณธ ๊ฐ์ ธ์ค๊ธฐ ๊ทธ๋ฃน์ ์ปฌ๋ ์ ์ด ์์ด์ผ๋ง ์๋ฏธ๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋๋ ๊ทธ๊ฒ์ ๋ฐฐ์ ํ๋ ๊ฒ์ด ๊ฒฐ์ฝ ์๋ฏธ๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
n Quarkus enableCollectionInDefaultFetchGroup์ด false๋ก ์ค์ ๋จ
์ฃ์กํฉ๋๋ค. ์, is set to true
๋ผ๊ณ ์ฐ๊ณ ์ถ์์ต๋๋ค. ์ ์ ์ฌ์ด๊ฐ๋ ์๊ฐ :-)
์ ๊ทธ๋ ๊ตฐ์ :-) ์ฌ์ธ์ :-)
@DavidD ํ๋ฅญํ ๋ฐ๊ฒฌ์ ๋๋ค. ๊ฐ์ฌํฉ๋๋ค :)
#374 ๋ฐ ๊ด๋ จ hibernate/hibernate-orm#3558์ ํ ๋ก ์ ๋ฐ๋ฅด๋ฉด enableCollectionInDefaultFetchGroup
๊ฐ Quarkus์์ ์๋์ ์ผ๋ก false
๋ก ๋จ๊ฒจ์ง ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค๋ ์ ์ ์ง์ ํ๊ณ ์ถ์์ต๋๋ค. ์ ์ด๋ ๊ทธ๊ฒ์ด ๋ด๊ฐ ์ด ๋๊ธ์์ ์์งํ๊ณ ์๋ ๊ฒ์
๋๋ค.
https://github.com/hibernate/hibernate-orm/pull/3558#issuecomment -695003875
์ด์จ๋ Quarkus๋ ํ์ฌ ํด๋น ์์ฑ์ true
์ค์ ํ์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค. FastBootReactiveEntityManagerFactoryBuilder
์์ ๊ตฌ์ฑ๋์ง ์์๊ธฐ ๋๋ฌธ์
๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ด๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ํ์ธํ๋ค๋ฉด Hibernate ORM์ ๊ธฐ๋ณธ๊ฐ์ ์ฌ์ ํ false
์ธ ๊ฒ ๊ฐ์ผ๋ฉฐ ์ด๋ Quarkus์์๋ง ์ด ๋์์ ๋ณผ ์ ์๋ ์ด์ ๋ฅผ ์ค๋ช
ํฉ๋๋ค.
@Sanne ์ ์ด๊ฒ์ ๋ด์ผํฉ๋๋ค.
true๋ก ์ค์ ํ๊ธฐ๋ง ํ๋ฉด ๋งค์ฐ ์ฝ๊ฒ ํด๊ฒฐํ ์ ์์ต๋๋ค. ์์ ์ฌํญ์ ์์ฑํ ๋ค์ @Sanne์๊ฒ ํ์ธํฉ๋๋ค.
๋ด๊ฐ ๊ถ๊ธํ ๊ฒ์ ๊ทธ๊ฒ์ด ORM์ด ํ์๋ก ํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ false๋ก ์ค์ ๋์ด ์๋์ง, ๊ทธ๋ฆฌ๊ณ ์ผ๋ฐ Hibernate๋ฅผ ๋ฐ์ง ์๋๋ก ์ฃผ์ํด์ผ ํ๋์ง ์ฌ๋ถ์ ๋๋ค.
์ข์ ๋ฐ๊ฒฌ, ๊ฐ์ฌํฉ๋๋ค. ์, ๋ ๊ฐ์ ํ์ฅ("์ผ๋ฐ" ๋ฐ "๋ฐ์")์ด ๊ณ ๋๋ก ๊ฒฐํฉ๋ ATM์ด๊ธฐ ๋๋ฌธ์ ์ฝ๊ฐ ๊น๋ค๋กญ์ต๋๋ค.
๊ทธ๊ฒ๋ค์ ์ ์ ํ๊ฒ ๋ถ๋ฆฌํ ํ์๊ฐ ์๋ค, ๊ทธ๊ฒ์ ๋๋ฌด ์๋๋ฅด๊ฒ ๊ฐ๋ฐ๋์๋ค.
(OTOH, ORM์ ์ ORM์ด ํ์ํ์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์ด์ ์ ์ฃผ์ฅํ๋ฏ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ์ผ์ ธ ์์ด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.)
ํ ์ข์. ๋ ORM(Quarkus์์) ๋ชจ๋์ ๋ํด ์ด ์์ ์ ์ํํด ๋ณด๊ฒ ์ต๋๋ค.
@gavinking , ์ ๋ชฉ์ด ์๋ชป๋ ๊ฒ ๊ฐ์๋ฐ์? ๋์ enableCollectionInDefaultFetchGroup
๋ฅผ ๋ฃ์ผ๋ ค๊ณ ํ๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ด์จ๋ ๋ค์ดํฐ๋ธ ๋๋ฌธ์ Quarkus์๋ ๋ฐ์ดํธ ์ฝ๋ ํฅ์์ด ํ์ํฉ๋๋ค. :)
์, ๋ค, ๋ค ๋ง์ด ๋ง๋ ๊ฒ ๊ฐ์์.
Quarkus์ ๊ธฐ๋ณธ ์ค์ ์ ์ด ๋ฒ๊ทธ๊ฐ ์๋ค๋ ๋ง์์ด์ ๊ฐ์?
์, ์ด ๋ฒ๊ทธ๋ฅผ ์ป๊ธฐ ์ํด Quarkus์์ ํน๋ณํ ๊ตฌ์ฑ์ด ํ์ํ์ง ์์ต๋๋ค. @DavidD ๋
ํ์ ํ๋.
๋ฌธ์ ๋ ์ค์ ๋ก HR์ ๋ฒ๊ทธ๊ฐ ์๋๋ผ๋ ๊ฒ์ ๋๋ค. ์ ๋ HR์์ ํญ์ ํ์ํ๊ธฐ ๋๋ฌธ์ "๊ธฐ๋ณธ ๊ฐ์ ธ์ค๊ธฐ ๊ทธ๋ฃน์ ์ปฌ๋ ์ "์ ์ฝ์ด์ ์๋์ ์ผ๋ก ์ถ๊ฐํ์ต๋๋ค.
๊ทธ๋์ ๋ฒ๊ทธ๋ ๊ทธ๊ฒ์ ๋๋ Quarkus ํ์ฅ์ ์์ต๋๋ค.
(๋๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์๋ชป๋ ์ผ์ ํ๋ ํต์ฌ์ ๋๋ค.)
Quarkus์ ๋ํ ์์ ์ฌํญ์ ๋ณด๋์ต๋๋ค: https://github.com/quarkusio/quarkus/pull/15818
getReference
๋ ํ์ฌ quarkus์์ ์๋ํ์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋๋ ๊ทธ๊ฒ์ ๋ํด ๋ณ๋์ ๋ฌธ์ ๋ฅผ ๋ง๋ค ๊ฒ์
๋๋ค.
์ ๋ค๋ฆฝ๋๋ค. ๊ฐ์ฌํฉ๋๋ค! ๐
๋ฐฉ๊ธ ํ ์คํธํ๊ณ ์ด์ Quarkus์์ ์ง์ฐ ์ปฌ๋ ์ ๊ฐ์ ธ์ค๊ธฐ๊ฐ ์๋ํ๋์ง ํ์ธํ ์ ์์ต๋๋ค. ๋ค์ ํ ๋ฒ ๊ฐ์ฌํฉ๋๋ค :์ค๋ง์ผ:
@markusdlugi ๊ฐ์ฌํฉ๋๋ค.
์ ๊ณ ํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค @markusdlugi
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๋ฐฉ๊ธ ํ ์คํธํ๊ณ ์ด์ Quarkus์์ ์ง์ฐ ์ปฌ๋ ์ ๊ฐ์ ธ์ค๊ธฐ๊ฐ ์๋ํ๋์ง ํ์ธํ ์ ์์ต๋๋ค. ๋ค์ ํ ๋ฒ ๊ฐ์ฌํฉ๋๋ค :์ค๋ง์ผ: