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

Provided SubscriptionExecutionStrategy is not used #430

Closed
vinterdo opened this issue Jun 23, 2020 · 4 comments
Closed

Provided SubscriptionExecutionStrategy is not used #430

vinterdo opened this issue Jun 23, 2020 · 4 comments
Labels
Milestone

Comments

@vinterdo
Copy link

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

@vinterdo vinterdo added the bug label Jun 23, 2020
@BartoszF
Copy link

I came across the same problem.
It would be nice, if someone with better understanding of how it's working underneath, would look at this.

@BartoszF
Copy link

BartoszF commented Aug 4, 2020

Looks similar to #358

@Aqu1nt
Copy link

Aqu1nt commented Nov 13, 2020

Can be solved by providing a custom GraphQLBuilder bean that overrides the default bean configured in GraphQLWebsocketAutoConfiguration.

    // Needed due to "Provided SubscriptionExecutionStrategy is not used #430"
    // https://github.com/graphql-java-kickstart/graphql-spring-boot/issues/430
    // @see GraphQLWebsocketAutoConfiguration#graphQLInvoker
    @Bean
    fun graphQLBuilder(executionStrategyProvider: ExecutionStrategyProvider): GraphQLBuilder {
        val builder = GraphQLBuilder()
        builder.executionStrategyProvider { executionStrategyProvider }
        return builder
    }

@oliemansm
Copy link
Member

The next version will pick the ExecutionStrategyProvider bean up and configure it automatically instead of having to provide your own GraphQLBuilder.

@oliemansm oliemansm added this to the 8.1.0 milestone Dec 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants