Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UnexpectedRollbackException for NonNullableFieldWasNullException when using @Transactional #927

Open
viico opened this issue Mar 19, 2024 · 1 comment
Labels
status: waiting-for-feedback We need additional information before we can continue status: waiting-for-triage An issue we've not yet triaged

Comments

@viico
Copy link

viico commented Mar 19, 2024

We want to use the @Transactional annotation in order to have one transaction by Query or Mutation. We added this annotation to a custom AsyncExecutionStrategy.

It works fine except for some exceptions, for example : NonNullableFieldWasNullException. This exception is not logged, it is only visible in the GraphQL response. Without the transactional annotation we have the correct response containing the error. But with the transactional annotation we didn't, an UnexpectedRollbackException is thrown. In this case the error is not logged and we have no idea of what is wrong.

We push a repository to reproduce the problem : https://github.com/viico/unexpectedrollbackexception. You can clone it, the class ProjectQueryResolverTest contains a test which should pass. It passes if we comment the transactional annotation (line 19 of TransactionalAsyncExecutionStrategyWithExceptionHandler class).

In the repo the exception NonNullableFieldWasNullException is thrown because we have a null field (label) which must not be null in the GrapQL schema.

For people who have the same problem : we have a workaround, you can log the error before UnexpectedRollbackException is thrown. The problem is still here but you have a log with the correct error, you can add the log in the custom AsyncExecutionStrategy :

    @Override
    @Transactional
    public CompletableFuture<ExecutionResult> execute(
            final ExecutionContext executionContext,
            final ExecutionStrategyParameters parameters
    ) throws NonNullableFieldWasNullException {
        return super.execute(executionContext, parameters).whenComplete((completeValueInfos, throwable) -> {
            if (throwable != null) {
                log.error("Error during GraphQL request execution", throwable);
            }
        });
    }
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Mar 19, 2024
@mp911de
Copy link
Member

mp911de commented Nov 7, 2024

Spring's transaction management rolls back transactions whenever it sees an unexpected exception. By default, that is every exception.

You can declare certain exceptions to be considered fine, in your case that would be @Transactional(noRollbackFor = NonNullableFieldWasNullException.class).

Spring's transaction management isn't aware of which exceptions are fine and what exceptions should lead to a rollback.

@mp911de mp911de added the status: waiting-for-feedback We need additional information before we can continue label Nov 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting-for-feedback We need additional information before we can continue status: waiting-for-triage An issue we've not yet triaged
Projects
None yet
Development

No branches or pull requests

3 participants