Mapping JPA OptimisticLockException Into HTTP Status Code 📎
A JAX-RS resource deployed as an EJB will wrap all exceptions into javax.ejb.EJBException
:
@Stateless
@Path("todos")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public class ToDosResource {
}
An javax.ejb.EJBException
can be easily transformed by an ExceptionMapper into a meaningful HTTP status code:
@Provider
public class EJBExceptionMapper implements ExceptionMapper<EJBException> {
@Override
public Response toResponse(EJBException ex) {
Throwable cause = ex.getCause();
if (cause instanceof OptimisticLockException) {
OptimisticLockException actual = (OptimisticLockException) cause;
return Response.status(Response.Status.CONFLICT).
header("cause", "conflict caused by entity: " + actual.getEntity()).
header("additional-info", actual.getMessage()).
build();
}
return Response.serverError().
header("cause", ex.toString()).build();
}
}
The 409 status code
"...Conflicts are most likely to occur in response to a PUT request. For example, if versioning were being used and the entity being PUT included changes to a resource which conflict with those made by an earlier (third-party) request, the server might use the 409 response to indicate that it can't complete the request..."is a natural HTTP representation of the OptimisticLockException.
The example above was taken from the DoIt sample application of the effectivejavaee.com online course.