After more investigation I’ve been able to narrow down the code path that will trigger the constraint violation to this:
@PersistenceContext(unitName = “Bizzaro”) private EntityManager entityMgr;
@EJB FooBean fooBean;
public void someBizMethod() { Request myRequest = entityMgr.find(Request.class, 123); fooBean.removeByName(myRequest.getName()); }
Inside FooBean (which is a SSB w/injected PU) removeByName is a CMT method which looks up Foo with a TypedQuery and then calls entityMgr.remove(foo); So something like this:
Foo myFoo = query.getSingleResult(); entityMgr.remove(myFoo); entityMgr.flush(); <— Explicit flush because I want to ensure this delete is ordered before subsequent recreate - triggers the constraint violation mentioned below
So now for the kicker. I thought, ok lets experiment and explicitly clear the entity manager in between the lookup of myRequest and the lookup/removal of myFoo so the flush shouldn’t be sending anything related to myRequest as it’s been cleared. So I tried that and low and behold I am getting the same results.
Foo does not contain a Request so how, after clearing the entity manager and in theory detaching myRequest, is a referential constraint between it and a BazFile object tripped?!
-Noah
That's interesting. You know, yes—some people don't—that the act of retrieving an object puts it in the persistence context? So if there's any modification to Request it will be "sent down" to the database, even if naively you thought you were just doing a query. I'm guessing you know this already but many of my teams over time have been burned by this.
Best, Laird
|