Reputation: 1426
According to the following sample class:
@Stateless
@Path("/evento")
public class EventoEndpoint {
@PersistenceContext
private EntityManager em;
@POST
@Consumes("application/json")
public Response create(Evento entity) throws Exception {
// Get a record from Bitacora table
TypedQuery<Bitacora> findBitacora = em.createQuery(
"SELECT b FROM Bitacora b WHERE b.id = :bitacoraId",
Bitacora.class);
findBitacora.setParameter("bitacoraId", entity.getBitacora().getId());
Bitacora bitacora = findBitacora.getSingleResult();
// Increment by one a field from the current bitacora record
Long interno = bitacora.getInterno() + 1;
// Assign the new number to entity.interno property
entity.setInterno(interno);
// Update number in bitacora record
bitacora.setInterno(interno);
// save bitacora record
em.persist(bitacora);
// an intentionally launched exception
if (interno > 0) throw new Exception("error en el sistema");
// save the entity
em.persist(entity);
// return a response
return Response.ok(user).build();
}
}
I expected that in this case, a call to the post method from a HTTP client had had to launch the exception so the database operations involved must to rollback.
It means, there should be no changes in database records at all.
Obviously that has not happened, because after launch the method, one entity is affected in database (bitacora) and the other one not (evento).
So, what is wrong in my code or how can I get a database transaction inside of a JAX-RS method?
Upvotes: 1
Views: 201
Reputation: 2464
Checked exceptions in EJBs are Application Exceptions by default. Throwing an Application Exception doesn't rollback the transaction unless configured to do so.
You can
@ApplicationException(rollback=true)
or the deployment descriptor.EJBContext.setRollbackOnly()
method to explicitly rollback the transaction.The spec contains all the details in chapters Support for Transactions and Exception Handling.
Upvotes: 2