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):
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_64java -version: OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)Additional context
@Unremovable and @RegisterForReflection on the subresource does not change the behaviourWould you please mind to explain where resourceContext is coming from?
@dfranssen sorry for the delay. Could you share a simple reproducer?
Would you please mind to explain where
resourceContextis 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.