On Tue, Feb 8, 2011 at 11:32 AM, Daryl Stultz <[email protected]>wrote:

> On Tue, Feb 8, 2011 at 11:08 AM, Michael Dick <[email protected]
> >wrote:
>
> > > getting the deleted object out of L1. I thought that if the object was
> > > modified prior to the JDBC delete, then another object was modified and
> > > "saved", the save transaction would cause the deleted but dirty object
> > > still
> > > in L1 to be saved as well (assuming it is still managed), but I can't
> > > demonstrate this in a unit test.
> > >
> >
> > Haven't tried that scenario myself, and I'd be interested to hear what
> you
> > find out if you have time to try it.
> >
> > Here's a unit test that exposes what I consider a big problem with the
> JPA
> architecture:
>
> Role job1 = setup.insertJob("XX_1"); // instantiates and inserts via
> ThreadLocal EM
> Role job2 = setup.insertJob("XX_2");
> System.out.println("job1.getId() = " + job1.getId());
> System.out.println("job2.getId() = " + job2.getId());
> // both jobs "managed"
> job1.setName("XX_newname_1");
> job2.setName("XX_newname_2");
> // both dirty and managed
> job2.save(); // begin transaction, merge, commit
> setup.resetEntityManagerForNewTransaction(); // close previous EM, open new
> one
> Role job1b = getEntityManager().find(Role.class, job1.getId());
> assertFalse(job1b == job1);
> assertEquals("XX_newname_1", job1b.getName()); // !!! this is not logical
> since I didn't "save" job1
> Role job2b = getEntityManager().find(Role.class, job2.getId());
> assertFalse(job2b == job2);
> assertEquals("XX_newname_2", job2b.getName()); // this is expected
> // part two
> job1b.setName("XX_newname_1b"); // job1b dirty
> deleteViaJdbc(job1b);
> job2b.setName("XX_newname_2b"); // job2b dirty
> try {
> job2b.save();
> fail("Expected exception");
> } catch (OptimisticLockException exc) { // trying to update deleted job
> exc.printStackTrace();
> }
> So I'm making changes to two objects, then saving just one of them. The
> side
> effect is that both objects are saved. I repeat the process but delete the
> changed object via JDBC. OpenJPA appears to be trying to save the deleted
> object. Here's the output:
>
> job1.getId() = 170
> job2.getId() = 171
> <openjpa-1.2.2-r422266:898935 nonfatal store error>
> org.apache.openjpa.persistence.OptimisticLockException: An optimistic lock
> violation was detected when flushing object instance
> "com.sixdegreessoftware.apps.rss.model.Role-170" to the data store.  This
> indicates that the object was concurrently modified in another transaction.
> FailedObject: com.sixdegreessoftware.apps.rss.model.Role-170
>
> I don't think OpenJPA should be expected to handle my JDBC delete, I'm just
> trying to illustrate why I called em.clear() after deleting via JDBC. It
> would make the second problem go away but lead to lazy load problems. The
> first problem marked with !!! is the "nature" of JPA I don't like and I'm
> having to find a workaround for since I have to do the delete via JDBC. At
> this point, I'm just hoping the "user" doesn't modify the object to be
> deleted.
>
> The main impact I foresee is that the other entities could have a reference
> > to a deleted row. Resulting in a constraint violation
> > at runtime. Then again, you're running that risk so long as you have the
> > legacy cron job that deletes rows unless your code gets a callback.
> >
>
> There are certain things the "user" should not expect to do after deleting
> an object, so if find() fails, that's OK. But the above scenario is a
> little
> harder to understand. Why can't I change a property on an object, delete
> it,
> then save some *other* object. I'm glazing over the problem of using JDBC
> to
> do the delete, of course, but you see my point.
>

I think I do. The problem is that with JPA you don't save the individual
objects. You save the persistence context.

Out of idle curiosity, why would one insert job1 right away? If you needed
the objects, but would selectively commit a subset of them, couldn't you
just create the POJO and merge later?

Or does insertJob start and complete its own transaction?

-mike

Reply via email to