I have problem with understanding the EJBTransactionRolledbackException.
I have entity:
@Entity
public class MyEntity {
@Id
@GeneratedValue
private Long id;
@Size(max=5)
private String name;
//...
}
and repository which is SLSB because of ease of CMT:
@Stateless
public class ExampleRepository {
@PersistenceContext
private EntityManager em;
public void add(MyEntity me) {
em.persist(me);
}
}
now I have test Servlet, when I simulate ConstraintViolation (too long name).
@WebServlet("/example")
public class ExampleServlet extends HttpServlet {
@Inject
private ExampleRepository repo;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
MyEntity me = new MyEntity();
me.setName("TooLongName");
try {
repo.add(me);
} catch(EJBTransactionRolledbackException e) {
System.out.println("Exception caught");
}
}
}
I know that in such scenario EJB container will wrap the ConstraintViolationException so I catch the EJBTransactionRolledbackException instead. The problem is that in the console I can see my message from catch block ("Exception caught") but before that there are tons of exception logs produced (link). I don't quite understand what happened - is this exception caught or not? How to prevent all these error messages in the console in such simple scenario?
Please look at this explanation: A clear explanation of system exception vs application exception
You have to understand that handling exceptions and handling transactions are two different things happening alongside. System exceptions unconditionally trigger transaction rollback. When you see a ConstraintViolationException
, which is a system exception because it extends RuntimeException
, it is not just wrapping and re-throwing. A bad thing have happened along the way - your transaction has been aborted.
So, answering the first question if the exception (ConstraintViolationException
) was caught - yes, it was caught by the container. The transaction was aborted and a new exception was thrown to notify the application code about that.
You can suppress logging these messages, but then you would not know about data persistence failures.