如何确定JPA中是否发生了Oracle延迟约束违规?

时间:2011-12-21 15:56:49

标签: oracle jpa

如果事务具有延迟约束违规,则Oracle 11g会在提交时静默回滚事务。实际获得错误的一种方法是在调用commit之前将约束设置为 immediate 。这可以使用Oracle SQL Developer正常工作,但在JPA(EclipseLink)本机查询中执行此操作会导致应用程序锁定。如果违反了延期约束,是否有任何替代方法可以通知?或者我可能没有正确使用JPA?

表格定义:

create table foo
(
foo_id integer not null,
order_id integer not null,
constraint foo_pk primary key (foo_id),
constraint foo_ak unique (order_id) deferrable
);

生成违规的SQL并查看控制台上显示的错误:

set constraint foo_ak deferred;
insert into foo values (1, 1);
insert into foo values (2, 1);
set constraint foo_ak immediate; -- Will rollback and display error

JPA尝试重新排序无状态会话Bean中的foo实体集合:

public void edit(List<Foo> foos) {
    Query deferred = em.createNativeQuery("set constraint foo_ak deferred");
    Query immediate = em.createNativeQuery("set constraint foo_ak immediate");

    deferred.executeUpdate(); // This works

    for(Foo f: foos) {
        em.merge(f); // This works too
    }

    immediate.executeUpdate(); // Hang with no output!
    // Note: if I comment out above line the transaction may 
    // be silently rolled back on deferred constraint violation
}

1 个答案:

答案 0 :(得分:1)

问题可以在语句缓存和应用服务器事务策略中。

尝试:

  • 强制实体管理器通过在执行{}执行后调用em.flush()将数据发送到数据库

和/或

  • 将@TransactionManagement属性更改为bean托管并管理方法中的事务