【问题标题】:Best way to handle constraint violations when using EJB 3.0 and CMP使用 EJB 3.0 和 CMP 时处理违反约束的最佳方法
【发布时间】:2011-11-03 14:45:25
【问题描述】:

我有一个 Web 服务(使用 jaxb/jaxws 构建),它调用无状态 EJB 以在数据库中存储一些数据。数据被存储为实体 bean。实体 bean 具有通过 @Column(unique = true) 注释应用到它的唯一约束。

当 Web 服务尝试保存数据时,事务会失败,这是理所当然的。问题是,因为我使用的是 CMP,所以直到调用无状态 EJB 之后才会提交事务。最终结果是我无法捕获异常,它被汇集到 WS 堆栈并导致包含字符串的模棱两可的错误:Error committing transaction:;nested exception is: weblogic.transaction.internal.AppSetRollbackOnlyException

有没有办法捕捉抛出的异常,以便我可以向调用者提供更多信息?谢谢。

版本信息:

  • 应用服务器:Oracle Weblogic 10.3
  • 持久性提供程序:Hibernate 3.2.5.ga (JPA 1.0)
  • JDK/JRE:1.6_0_05(由 Weblogic 安装提供)

更新: 我试图围绕方法调用实现一个 EJB 3 拦截器,但这似乎不起作用。

public class TestInterceptor {

@AroundInvoke
public Object logCall(InvocationContext context) throws Exception {

    System.out.println("Invoking method: " + context.getMethod().getName());

    try {
        return context.proceed();
    } catch (Throwable t) {
        System.out.println("I caught an exception: " + t.getMessage());
        throw new Exception(t);
    }

}

我认为这不起作用的原因是因为处理链使得实际持久化发生在方法之外(当然)。

【问题讨论】:

    标签: jpa ejb-3.0 jax-ws


    【解决方案1】:

    您可以尝试使用Bean Validation。它与 JPA 很好地连接(在 pre-persist、pre-update 和 pre-remove 阶段调用,并且可以在应用程序的不同层中使用。

    不幸的是,据我所知,如果发生验证约束违规,事务将被标记为回滚...我不知道您如何应对,但有一个(看起来很讨厌且未经测试) 我能想到的方法是注入一个 ValidatorFactory 并自己验证对象。也许那时你可以捕捉到 ValidationException。

    编辑:我不确定 Bean Validation 在 Java EE 5 中是否可用。

    编辑 2: 您可以创建一个拦截器,该拦截器将捕获 JPA(或更准确地说是数据库)抛出的异常。由于拦截器作为与 EJB 方法相同的事务的一部分被调用,因此您可能需要显式调用 EntityManager#flush(-) 以将更改与数据库同步。

    【讨论】:

    • 我不熟悉 Bean 验证,但在我看来,即使验证了 bean,当对象实际保存在数据库中时,与唯一字段相关的约束验证也可以已经发生,所以问题仍然存在。您是正确的,因为 Bean Validation 在 JEE5 中似乎不可用。
    • @babernat 是的,如前所述 - Bean 验证发生在 pre-* 阶段,因此如果您想检查 DB 约束,您只能在真正访问 DB 期间检查它们。您可能还记得您可以捕获 runtimeException 并抛出一些@ApplicationException,这更类似于实际发生的情况。您可以在拦截器中执行此操作,以将其与您的业务逻辑分离。
    • 我尝试了拦截器方法(请参阅已编辑的问题),但似乎事务在我的拦截器被调用后提交,因此我无法使用拦截器捕获它。那是除非我写错了我的拦截器。
    • 您可能希望在使用的 EntityManager 上调用显式刷新。
    • 显式刷新 EntityManager 确实有效,我可以捕获生成的异常并处理它。 +1 并接受帮助。
    猜你喜欢
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多