5

我试图通过约束验证来持久化实体,当调用持久化时 - 抛出约束并且调用者获取EjbTransactionRolledbackException......所以我尝试显式调用验证并抛出ConstraintViolationException/RuntimeException仍然调用者获取EjbTransactionRolledbackException......当我抛出MyException扩展Exception- 调用者得到MyException

即使我明确表示sc.setRollBackOnly它仍然发生:(

这不应该是行为。

这是怎么回事?

配置:

Netbeans 6.9.1 Glassfish 3.0.1 JPA 2.0 (EclipseLink) EJB 3.1

谢谢!!!

@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);
}
4

2 回答 2

11

所以我尝试显式调用验证并抛出 ConstraintViolationException/RuntimeException 并且调用者仍然得到 EjbTransactionRolledbackException ...

提供完整的堆栈跟踪可能会有所帮助。无论如何,我想知道您是如何调用您的 EJB 的,以及您是否正在传播事务,在这种情况下,抛出 EJBTransactionRolledbackException 是系统异常情况下的正确行为。但是以下博客文章可能会有所帮助:

违反约束,事务回滚

在 EJB 3 bean 中对 JPA 实体使用 bean 验证时,如果存在约束冲突,您实际上会得到 EJBTransactionRolledbackException。

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, ]

这一切都很好地符合规范,但不是真正有趣的信息。你真的不想知道发生了什么,你想知道出了什么问题。

所以我建议将以下内容添加到您的 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>

这样您就可以直接访问您的违规行为。

资源

于 2010-09-25T12:27:20.430 回答
0

只是为了整合@Pascal的答案,也可以用

 @javax.ejb.ApplicationException(rollback = true)
 public class UncheckedException extends RuntimeException {...}
于 2020-04-10T13:20:30.780 回答