Quarkus で session is currently connecting to database エラーが出た場合

Quarkus に Hibernate Reactive with Panache を入れて DB からデータを取得しようとした時に、件のエラーが出たので対処方法を紹介します。

問題のソースはこちらです。

@Path("/post")
public class PostResource {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Uni<Paginated<Post>> list(@QueryParam("page") @DefaultValue("0") int page) {
        // 1ページ分のデータ取得
        Uni<List<Post>> listUni = Post.findAll().page(page, 12).list();
        // 総件数取得
        Uni<Long> countUni = Post.count();

        var result = Uni.combine().all().unis(listUni, countUni).combinedWith((list, count) -> {
            return Paginated.create(list, page, count);
        });
        return result;
    }
}

データ取得だけならばエラーにならなかったのですが、総件数を一緒に取得するよう変更したところ以下のようなエラーが出ました。

ERROR [org.jbo.res.rea.ser.cor.ExceptionMapping] (vert.x-eventloop-thread-8) Request failed : java.lang.IllegalStateException: session is currently connecting to database
        at org.hibernate.reactive.pool.impl.ProxyConnection.withConnection(ProxyConnection.java:52)
        at org.hibernate.reactive.pool.impl.ProxyConnection.selectJdbc(ProxyConnection.java:109)
        at org.hibernate.reactive.loader.ReactiveLoader.executeReactiveQueryStatement(ReactiveLoader.java:129)
        at org.hibernate.reactive.loader.ReactiveLoader.doReactiveQueryAndInitializeNonLazyCollections(ReactiveLoader.java:69)
        at org.hibernate.reactive.loader.CachingReactiveLoader.doReactiveList(CachingReactiveLoader.java:62)
        at org.hibernate.reactive.loader.CachingReactiveLoader.reactiveListIgnoreQueryCache(CachingReactiveLoader.java:80)
        at org.hibernate.reactive.loader.hql.impl.ReactiveQueryLoader.reactiveList(ReactiveQueryLoader.java:129)
        at org.hibernate.reactive.loader.hql.impl.ReactiveQueryLoader.reactiveList(ReactiveQueryLoader.java:95)
        at org.hibernate.reactive.session.impl.ReactiveQueryTranslatorImpl.reactiveList(ReactiveQueryTranslatorImpl.java:139)
        at org.hibernate.reactive.session.impl.ReactiveHQLQueryPlan.performReactiveList(ReactiveHQLQueryPlan.java:114)
        at org.hibernate.reactive.session.impl.ReactiveSessionImpl.lambda$reactiveList$8(ReactiveSessionImpl.java:438)
        at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1106)
        at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2235)
        at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:143)
        at org.hibernate.reactive.session.impl.ReactiveSessionImpl.reactiveList(ReactiveSessionImpl.java:438)
        at org.hibernate.reactive.session.impl.ReactiveQueryImpl.doReactiveList(ReactiveQueryImpl.java:133)
        at org.hibernate.reactive.session.impl.ReactiveQueryImpl.getReactiveResultList(ReactiveQueryImpl.java:109)
        at org.hibernate.reactive.session.impl.ReactiveQueryImpl.getReactiveSingleResult(ReactiveQueryImpl.java:84)
        at io.smallrye.context.impl.wrappers.SlowContextualSupplier.get(SlowContextualSupplier.java:21)
        at io.smallrye.mutiny.operators.uni.builders.UniCreateFromCompletionStage.subscribe(UniCreateFromCompletionStage.java:24)
        at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
        at io.smallrye.mutiny.operators.uni.UniRunSubscribeOn.lambda$subscribe$0(UniRunSubscribeOn.java:27)
        at org.hibernate.reactive.mutiny.impl.MutinySessionFactoryImpl.lambda$new$1(MutinySessionFactoryImpl.java:53)
        at io.smallrye.mutiny.operators.uni.UniRunSubscribeOn.subscribe(UniRunSubscribeOn.java:25)
        at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
        at io.smallrye.mutiny.operators.uni.UniAndCombination$UniHandler.subscribe(UniAndCombination.java:203)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
        at io.smallrye.mutiny.operators.uni.UniAndCombination$AndSupervisor.run(UniAndCombination.java:71)
        at io.smallrye.mutiny.operators.uni.UniAndCombination$AndSupervisor.access$000(UniAndCombination.java:53)
        at io.smallrye.mutiny.operators.uni.UniAndCombination.subscribe(UniAndCombination.java:50)
        at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
        at io.smallrye.mutiny.groups.UniSubscribe.withSubscriber(UniSubscribe.java:50)
        at io.smallrye.mutiny.groups.UniSubscribe.with(UniSubscribe.java:90)
        at org.jboss.resteasy.reactive.server.handlers.UniResponseHandler.handle(UniResponseHandler.java:17)
        at org.jboss.resteasy.reactive.server.handlers.UniResponseHandler.handle(UniResponseHandler.java:8)
        at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:122)
        at org.jboss.resteasy.reactive.server.handlers.RestInitialHandler.beginProcessing(RestInitialHandler.java:47)
        at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:17)
        at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:7)
        at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1038)
        at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:137)
        at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:132)
        at io.quarkus.vertx.http.runtime.StaticResourcesRecorder.lambda$start$1(StaticResourcesRecorder.java:65)
        at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1038)
        at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:101)
        at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:132)
        at io.vertx.ext.web.handler.impl.StaticHandlerImpl.lambda$sendStatic$1(StaticHandlerImpl.java:206)
        at io.vertx.core.impl.ContextImpl.lambda$null$0(ContextImpl.java:327)
        at io.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:366)
        at io.vertx.core.impl.EventLoopContext.lambda$executeAsync$0(EventLoopContext.java:38)
        at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
        at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
        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)
        at java.base/java.lang.Thread.run(Thread.java:829)

どうやら複数のクエリを投げる時は以下のようにトランザクションを張らなければいけないようです。

@Path("/post")
public class PostResource {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Uni<Paginated<Post>> list(@QueryParam("page") @DefaultValue("0") int page) {
        return Panache.withTransaction(() -> {
            // 1ページ分のデータ取得
            Uni<List<Post>> listUni = Post.findAll().page(page, 12).list();
            // 総件数取得
            Uni<Long> countUni = Post.count();

            var result = Uni.combine().all().unis(listUni, countUni).combinedWith((list, count) -> {
                return Paginated.create(list, page, count);
            });
            return result;
        });
    }
}

参考

Quarkus のバージョン: 1.13.6

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください