Oracle 11g silently rolls back a transaction upon commit if the transaction has a deferred constraint violation. One way to actually get an error is to set the constraint to immediate before calling commit. This works fine using Oracle SQL Developer, but doing this in a JPA (EclipseLink) native query results in the application locking up. Is there any alternative way to be notified if a deferred constraint was violated? Or perhaps I’m not using JPA correctly?
Table definition:
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 to generate violation and see error displayed on console:
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 attempting to reorder a collection of foo entities in Stateless Session Bean:
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
}
Problem can be in statement caching and in application server transaction strategy.
Try to:
and/or