Skip to content
This repository was archived by the owner on Dec 19, 2023. It is now read-only.
This repository was archived by the owner on Dec 19, 2023. It is now read-only.

Provided SubscriptionExecutionStrategy is not used #430

Closed
@vinterdo

Description

@vinterdo

Hello,

I tried to create a subscription, where I send info every time an Entity (from Hibernate) is updated. I encountered similar problem as with queries - LazyInitializationException. In the case of Queries, it was easily resolved by creating custom execution strategy, where execute is annotated as Transactional:

@Service
open class TransactionalQueryExecutionStrategy : AsyncExecutionStrategy() {

    @Transactional
    override fun execute(executionContext: ExecutionContext, parameters: ExecutionStrategyParameters): CompletableFuture<ExecutionResult> {
        return super.execute(executionContext, parameters)
    }
}

For subscription, I created something similar, except executeSubscriptionEvent method is annotated as Transactional.
And is injected by creating DefaultExecutionStrategyProvider:

    @Bean
    open fun executionStrategies(
            queryExecutionStrategy: TransactionalQueryExecutionStrategy,
            mutationExecutionStrategy: TransactionalMutationExecutionStrategy,
            subscriptionExecutionStrategy: TransactionalSubscriptionExecutionStrategy
    ) : ExecutionStrategyProvider {
        return DefaultExecutionStrategyProvider(queryExecutionStrategy, mutationExecutionStrategy, subscriptionExecutionStrategy)
    }

It works for queries and mutations like a charm. But for subscriptions, the problem is still there:

java.util.concurrent.CompletionException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: pl.vinterdo.sto.gamesession.entities.GameSession.invitedPlayers, could not initialize proxy - no Session
	at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:331) ~[na:na]
	at java.base/java.util.concurrent.CompletableFuture.uniApplyNow(CompletableFuture.java:670) ~[na:na]
	at java.base/java.util.concurrent.CompletableFuture.uniApplyStage(CompletableFuture.java:658) ~[na:na]
	at java.base/java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:2094) ~[na:na]
	at graphql.execution.SubscriptionExecutionStrategy.executeSubscriptionEvent(SubscriptionExecutionStrategy.java:104) ~[graphql-java-14.0.jar:na]
	at graphql.execution.SubscriptionExecutionStrategy.lambda$null$0(SubscriptionExecutionStrategy.java:47) ~[graphql-java-14.0.jar:na]
	at graphql.execution.reactive.CompletionStageMappingPublisher$1.onNext(CompletionStageMappingPublisher.java:47) ~[graphql-java-14.0.jar:na]
	at io.reactivex.rxjava3.internal.util.HalfSerializer.onNext(HalfSerializer.java:45) ~[rxjava-3.0.4.jar:na]
	at io.reactivex.rxjava3.internal.subscribers.StrictSubscriber.onNext(StrictSubscriber.java:97) ~[rxjava-3.0.4.jar:na]
	at io.reactivex.rxjava3.internal.operators.flowable.FlowableConcatArray$ConcatArraySubscriber.onNext(FlowableConcatArray.java:77) ~[rxjava-3.0.4.jar:na]
	at io.reactivex.rxjava3.internal.subscriptions.ScalarSubscription.request(ScalarSubscription.java:55) ~[rxjava-3.0.4.jar:na]
	at io.reactivex.rxjava3.internal.subscriptions.SubscriptionArbiter.setSubscription(SubscriptionArbiter.java:99) ~[rxjava-3.0.4.jar:na]
	at io.reactivex.rxjava3.internal.operators.flowable.FlowableConcatArray$ConcatArraySubscriber.onSubscribe(FlowableConcatArray.java:71) ~[rxjava-3.0.4.jar:na]
	at io.reactivex.rxjava3.internal.operators.flowable.FlowableJust.subscribeActual(FlowableJust.java:34) ~[rxjava-3.0.4.jar:na]
	at io.reactivex.rxjava3.core.Flowable.subscribe(Flowable.java:15750) ~[rxjava-3.0.4.jar:na]
	at io.reactivex.rxjava3.core.Flowable.subscribe(Flowable.java:15696) ~[rxjava-3.0.4.jar:na]
	at io.reactivex.rxjava3.internal.operators.flowable.FlowableConcatArray$ConcatArraySubscriber.onComplete(FlowableConcatArray.java:140) ~[rxjava-3.0.4.jar:na]
	at io.reactivex.rxjava3.internal.operators.flowable.FlowableConcatArray.subscribeActual(FlowableConcatArray.java:40) ~[rxjava-3.0.4.jar:na]
	at io.reactivex.rxjava3.core.Flowable.subscribe(Flowable.java:15750) ~[rxjava-3.0.4.jar:na]
	at io.reactivex.rxjava3.core.Flowable.subscribe(Flowable.java:15699) ~[rxjava-3.0.4.jar:na]
	at graphql.execution.reactive.CompletionStageMappingPublisher.subscribe(CompletionStageMappingPublisher.java:34) ~[graphql-java-14.0.jar:na]
	at graphql.kickstart.execution.subscriptions.DefaultSubscriptionSession.subscribe(DefaultSubscriptionSession.java:37) ~[graphql-java-servlet-9.1.0.jar:na]
	at graphql.kickstart.execution.subscriptions.apollo.SubscriptionStartCommand.handleSubscriptionStart(SubscriptionStartCommand.java:46) ~[graphql-java-servlet-9.1.0.jar:na]
	at graphql.kickstart.execution.subscriptions.apollo.SubscriptionStartCommand.lambda$apply$1(SubscriptionStartCommand.java:32) ~[graphql-java-servlet-9.1.0.jar:na]
	at java.base/java.util.concurrent.CompletableFuture.uniAcceptNow(CompletableFuture.java:753) ~[na:na]
	at java.base/java.util.concurrent.CompletableFuture.uniAcceptStage(CompletableFuture.java:731) ~[na:na]
	at java.base/java.util.concurrent.CompletableFuture.thenAccept(CompletableFuture.java:2108) ~[na:na]
	at graphql.kickstart.execution.subscriptions.apollo.SubscriptionStartCommand.apply(SubscriptionStartCommand.java:32) ~[graphql-java-servlet-9.1.0.jar:na]
	at graphql.kickstart.execution.subscriptions.apollo.ApolloSubscriptionConsumer.accept(ApolloSubscriptionConsumer.java:24) ~[graphql-java-servlet-9.1.0.jar:na]
	at graphql.kickstart.execution.subscriptions.apollo.ApolloSubscriptionConsumer.accept(ApolloSubscriptionConsumer.java:11) ~[graphql-java-servlet-9.1.0.jar:na]
	at graphql.kickstart.servlet.GraphQLWebsocketServlet$1.onMessage(GraphQLWebsocketServlet.java:127) ~[graphql-java-servlet-9.1.0.jar:na]
	at graphql.kickstart.servlet.GraphQLWebsocketServlet$1.onMessage(GraphQLWebsocketServlet.java:123) ~[graphql-java-servlet-9.1.0.jar:na]
	at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:395) ~[tomcat-embed-websocket-9.0.33.jar:9.0.33]
	at org.apache.tomcat.websocket.server.WsFrameServer.sendMessageText(WsFrameServer.java:119) ~[tomcat-embed-websocket-9.0.33.jar:9.0.33]
	at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:495) ~[tomcat-embed-websocket-9.0.33.jar:9.0.33]
	at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:294) ~[tomcat-embed-websocket-9.0.33.jar:9.0.33]
	at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:133) ~[tomcat-embed-websocket-9.0.33.jar:9.0.33]
	at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:82) ~[tomcat-embed-websocket-9.0.33.jar:9.0.33]
	at org.apache.tomcat.websocket.server.WsFrameServer.doOnDataAvailable(WsFrameServer.java:171) ~[tomcat-embed-websocket-9.0.33.jar:9.0.33]
	at org.apache.tomcat.websocket.server.WsFrameServer.notifyDataAvailable(WsFrameServer.java:151) ~[tomcat-embed-websocket-9.0.33.jar:9.0.33]
	at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:148) ~[tomcat-embed-websocket-9.0.33.jar:9.0.33]
	at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:54) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:59) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1594) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.33.jar:9.0.33]
	at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

As you can see from stack trace, subscription execution strategy from graphql java is used, not the one I provided.

I also tried using map to inject my strategies, with strategies renamed to expected names:

@Bean
    open fun executionStrategies() : ExecutionStrategyProvider {
        return DefaultExecutionStrategyProvider(QueryExecutionStrategy(), MutationExecutionStrategy(), SubscriptionExecutionStrategy());
        executionStrategyMap[QUERY_EXECUTION_STRATEGY] = QueryExecutionStrategy()
        executionStrategyMap[MUTATION_EXECUTION_STRATEGY] =
        executionStrategyMap[SUBSCRIPTION_EXECUTION_STRATEGY] =
        return executionStrategyMap;
    }

But the effect was the same

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions