I am trying to per开发者_开发百科sist 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);
}
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
- On EJB and application vs system exception:
- Best practices in EJB exception handling
- 16.6. Exceptions and Transactions
- On Bean Validation
- Constraint violated, transaction rolled back
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 {...}
精彩评论