Skip to content

Instantly share code, notes, and snippets.

@nicmarti
Created May 9, 2020 17:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicmarti/ffae5f7fdba7830fc6c3a83226842a09 to your computer and use it in GitHub Desktop.
Save nicmarti/ffae5f7fdba7830fc6c3a83226842a09 to your computer and use it in GitHub Desktop.
Quarkus RESTEasy and update with Transaction
@ApplicationScoped
public class ProjectService {
@Inject
UserTransaction transaction;
private static Logger logger = LoggerFactory.getLogger(ProjectService.class);
@Inject
ClientService clientService;
@Inject
UserService userService;
public Optional<Long> update(Long id, ProjectRequest request, AuthenticationContext ctx) {
logger.debug("Modify project for for id={} with {}, {}", id, request, ctx);
try {
transaction.begin(); // See https://quarkus.io/guides/transaction API Approach
final var updatedProject = findById(id, ctx)
.stream()
.map(project -> request.unbind(project, clientService::findById, userService::findById, ctx))
.peek(project -> project.users
.stream()
.filter(request::notContains)
.forEach(PanacheEntityBase::delete))
.map(project -> project.id)
.findFirst();
transaction.commit();
return updatedProject;
} catch (Throwable e) {
// There are many various exceptions, we catch Throwable but this is arguable.
logger.warn("Could not update a Project due to an exception {}", e.getMessage());
try {
if (transaction.getStatus() != Status.STATUS_MARKED_ROLLBACK && transaction.getStatus() != Status.STATUS_NO_TRANSACTION) {
transaction.rollback();
}
} catch (SystemException ex) {
logger.error("Tried to rollback in ProjectService but failed",ex);
}
throw new UpdateResourceException("Cannot update a Project, invalid projectRequest");
}
}
// ....
}
@nicmarti
Copy link
Author

nicmarti commented May 9, 2020

This is an extract from a project we're working on.

The ProjectService is injected into a REST ProjectResource. The transactional annotation is not used, since we're trying to trigger a validation on update. Due to Panache, we cannot use a persistAndFlush() here. Thus the only solution I found was to use the UserTransaction as explained in Quarkus documentation
https://quarkus.io/guides/transaction

The unbind method is a custom BiFunction method, created by @Fabszn, that unwrapp a ProjectRequest, try to lookup and to resolve the client and the user that are required to update a Project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment