Why session bean method throw EjbTransactionRolledbackException when RuntimeException was thrown
Asked Answered
S

2

5

I am trying to persist the entity with constraint validation, when invoke persist - there is constraint that thrown and the caller get EjbTransactionRolledbackException... so I try to call the validation explicit and throw ConstraintViolationException/RuntimeException and still the caller get EjbTransactionRolledbackException... when I throw MyException extends Exception - the caller get MyException

Even when I call explicit sc.setRollBackOnly it's still happened :(

This shouldn't be the behavior.

what's going on?

Configuration:

Netbeans 6.9.1 Glassfish 3.0.1 JPA 2.0 (EclipseLink) EJB 3.1

Thanks!!!

@Stateless
public class My {

@PersistenceContext
EntityManager em;

@Resource
Validator  validator;

public Order checkout(Order order) {
    Set<ConstraintViolation<Order>> set = validator.validate(order, Default.class);

    if (!set.isEmpty()) {
        sc.setRollbackOnly();
        //throw new ConstraintViolationException(new HashSet<ConstraintViolation<?>>(set));
        throw new RuntimeException();
    }

    this.em.persist(order);
}
Stagy answered 25/9, 2010 at 11:45 Comment(0)
P
11

so I try to call the validation explicit and throw ConstraintViolationException/RuntimeException and still the caller get EjbTransactionRolledbackException...

Providing the full stacktrace might help. Anyway, I wonder how you are calling your EJB and if you're propagating a transaction, in which case throwing a EJBTransactionRolledbackException is the right behavior in case of a system exception. But the following blog post might help:

Constraint violated, transaction rolled back

When using bean validation on JPA entities within an EJB 3 bean you would actually get an EJBTransactionRolledbackException if there is a constraint violation.

javax.ejb.EJBTransactionRolledbackException: Invalid object at persist time for groups [javax.validation.groups.Default, ]
Caused by: javax.validation.ConstraintViolationException: Invalid object at persist time for groups [javax.validation.groups.Default, ]

This is all nicely according to specification, but not really interesting information. You don't really want to know what happened, you want to know what went wrong.

So I recommend adding the following to your ejb-jar.xml:

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                            http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
        version="3.0">
   <assembly-descriptor>
      <application-exception>
         <exception-class>javax.validation.ConstraintViolationException</exception-class>
         <rollback>true</rollback>
      </application-exception>
   </assembly-descriptor>
</ejb-jar>

That way you can directly access your violations.

Resources

Plasmasol answered 25/9, 2010 at 12:27 Comment(2)
<?xml version="1.0" encoding="UTF-8"?> <ejb-jar xmlns="java.sun.com/xml/ns/javaee" xmlns:xsi="w3.org/2001/XMLSchema-instance" xsi:schemaLocation="java.sun.com/xml/ns/javaee java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" version="3.0"> <assembly-descriptor> <application-exception> <exception-class>javax.validation.ConstraintViolationException</exception-class> <rollback>true</rollback> </application-exception> </assembly-descriptor> </ejb-jar>Stagy
Great answer! if I put the above XML in the ejb-jar.xml, I tell to the EJB context that if javax.validation.ConstraintViolationException was thrown, the caller will get application exception (without destroying the session bean) and not a system exceptionStagy
A
0

Just to integrate @Pascal's answer, it is also possible to mark Exception (if it's on your own) with

 @javax.ejb.ApplicationException(rollback = true)
 public class UncheckedException extends RuntimeException {...}
Apologete answered 10/4, 2020 at 13:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.