quarkusio/quarkus

Transactional not working in JAX-RS subresource

Closed this issue · 7 comments

Describe the bug
A method annotated with @Transactional in a JAX-RS subresource doesn't persist the entity

Expected behavior
The entity should be persisted

Actual behavior
The entity is not persisted

To Reproduce

see https://github.com/dfranssen/quarkus-tx-issue-subresources for a reproducer

Parent resource:

@RequestScoped
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("tenants")
@NoCache
public class TenantsResource {

@Context
ResourceContext resourceContext;

@Path("{tenantId}/cards")
    public TenantCardsResource cardsResource() {
        return resourceContext.initResource(new TenantCardsResource(keycloakSecurityContext, keycloakIntegrator, entityBuilder));
    }
}

Subresource:

@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@RequestScoped
public class TenantCardsResource {
    @PathParam("tenantId")
    String tenantId;

    @PUT
    @Path("{cardId}/unassign")
    @Transactional
    public Response unassignCard(@PathParam("cardId") long cardId) {
        Card card = findCard(cardId, tenantId);
        card.setUserId(null);
        card.persist();
        return Response.noContent().build();
    }
}

Environment (please complete the following information):

  • Output of uname -a or ver: Darwin Dirks-MacBook-Pro-3.local 18.6.0 Darwin Kernel Version 18.6.0: Thu Apr 25 23:16:27 PDT 2019; root:xnu-4903.261.4~2/RELEASE_X86_64 x86_64
  • Output of java -version: OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)
  • Quarkus version or git rev: 0.22.0

Additional context

  • Postgres DB
  • Adding @Unremovable and @RegisterForReflection on the subresource does not change the behaviour

Would you please mind to explain where resourceContext is coming from?

gsmet commented

@dfranssen sorry for the delay. Could you share a simple reproducer?

Would you please mind to explain where resourceContext is coming from?

@context
ResourceContext resourceContext;

@gsmet see https://github.com/dfranssen/quarkus-tx-issue-subresources for a reproducer

In short: although having @Transactional on the parent and child resource methods, executing ParentChildResourceTest results in: TransactionRequiredException: Transaction is not active, consider adding @Transactional to your method to automatically activate one

@gsmet is there missing some information in order to get it assigned to a release?

@dfranssen I claim, this won't work if you instantiate the bean yourself (then it's not managed by the container/runtime and no aspects such as transactions are handled).

Have you tried

  1. in the parent: injecting with @Inject ChildResource childResource and then, in your method, passing that to resourceContext.initResource(childResource)
    OR
  2. using resourceContext.getResource(ChildResource.class) (for which you probably have to annotate ChildResource with @Unremovable for now, due to #5314)

There is nothing we can do here, as you are creating the bean yourself. You need to inject the sub resource for CDI to be able to intercept it.