Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Entity must be managed to call remove
Entity must be managed to call remove [message #383827] Thu, 27 November 2008 09:55 Go to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 807
Registered: July 2009
Senior Member
And this is the code being executed:

// delete the batchcount
lBatchcount.setFromAmountBatchtransferline(null);
lBatchcount.setBatch(null);
lEntityManager.merge(lBatchcount);
lEntityManager.remove(lBatchcount);

If I run this from within a standalone test case, this works ok. If I run it from within the bowls of my application, I get this exception:

java.lang.IllegalArgumentException: Entity must be managed to call remove: nl.reinders.bm.Batchcount@f1d30f, Batchcountnr=1330155, try merging the detached and try the remove again.
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.per formRemove(UnitOfWorkImpl.java:3251)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.remov e(EntityManagerImpl.java:283)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.tbee.util.jpa.EntityManagerExtender.invoke(EntityManager Extender.java:102)
at $Proxy32.remove(Unknown Source)
at nl.reinders.bm.Batchcount.changeAllocationTo(Batchcount.java :88)
at nl.reinders.bm.Batchtransferline.updateBatchcount(Batchtrans ferline.java:92)
at nl.reinders.gui.batchtransfer.BatchtransferObjectNavigator$3 .duringSavePostMerge(BatchtransferObjectNavigator.java:103)
at nl.reinders.gui.batchtransfer.BatchtransferObjectNavigator$3 .duringSavePostMerge(BatchtransferObjectNavigator.java:1)
at org.tbee.swing.jpa.JpaObjectNavigatorModel.duringSavePostMer ge(JpaObjectNavigatorModel.java:1026)
at org.tbee.swing.jpa.JpaObjectNavigatorModel.doSave(JpaObjectN avigatorModel.java:745)
at org.tbee.swing.jpa.JpaObjectNavigatorBar$3.actionPerformed(J paObjectNavigatorBar.java:125)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButto n.java:1995)


Can anyone shed a light on how this exception can happen? I mean, the entity is really really merged before remove. So there must be something else at work here.

Tom
Re: Entity must be managed to call remove [message #384208 is a reply to message #383827] Thu, 27 November 2008 11:18 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 807
Registered: July 2009
Senior Member
> Can anyone shed a light on how this exception can happen? I mean, the
> entity is really really merged before remove. So there must be something
> else at work here.


Right. And gone is the exception.

If a clear is run before the transaction. the exception occurs. Note the commented out clear in the second commit.

// commit
lEntityManager.clear(); // prevent errors from a previous store session (not rollbacked optimistic lock increments) to screw things up
lEntityManager.getTransaction().begin();
lBatchtransferline.updateBatchcount(); // insert always ok
lEntityManager.getTransaction().commit();

System.out.println(" ------------------------------------------------------------ ---------------------- ");

// decrement (causing a remove)
lBatchtransferline = Batchtransferline.findByPK(18);
lBatchtransferline.setFromAmount(BigInteger.valueOf(50));

// commit
//lEntityManager.clear(); // prevent errors from a previous store session (not rollbacked optimistic lock increments) to screw things up
lEntityManager.getTransaction().begin();
lBatchtransferline.updateBatchcount(); // remove error
lEntityManager.getTransaction().commit();


Now, I had to make some tweaks to the EntityManager and EntityTransaction in order to allow the make-all-changes-outside-a-transaction to work. So it may be associated with that.
Re: Entity must be managed to call remove [message #384209 is a reply to message #384208] Thu, 27 November 2008 11:30 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 807
Registered: July 2009
Senior Member
> Now, I had to make some tweaks to the EntityManager and
> EntityTransaction in order to allow the
> make-all-changes-outside-a-transaction to work. So it may be associated
> with that.

No, it has nothing to do with my own tweaks. This is the test code:

// entitymanagerfactory
EntityManagerFactory lEntityManagerFactory = BM.createEntityManagerFactory(com.informix.jdbc.IfxDriver.cl ass, " jdbc:informix-sqli://toeu_reinders:1527/reinders:INFORMIXSER VER=ol_ids10;DB_LOCALE=en_us.utf8", "user", "user");

// entitymanager
EntityManager lEntityManager = lEntityManagerFactory.createEntityManager();
org.tbee.util.jpa.EntityManagerFinderSingleton.register();
org.tbee.util.jpa.EntityManagerFinderSingleton.setEntityMana ger(lEntityManager);
System.out.println(lEntityManager.getClass());

// increment
Batchtransferline lBatchtransferline = Batchtransferline.findByPK(18);
lBatchtransferline.setFromAmount(BigInteger.valueOf(100));

// commit
lEntityManager.clear(); // prevent errors from a previous store session (not rollbacked optimistic lock increments) to screw things up
lEntityManager.getTransaction().begin();
lBatchtransferline.updateBatchcount(); // insert always ok
lEntityManager.getTransaction().commit();

System.out.println(" ------------------------------------------------------------ ---------------------- ");

// decrement (causing a remove)
lBatchtransferline = Batchtransferline.findByPK(18);
lBatchtransferline.setFromAmount(BigInteger.valueOf(50));

// commit
lEntityManager.clear(); // prevent errors from a previous store session (not rollbacked optimistic lock increments) to screw things up
lEntityManager.getTransaction().begin();
lBatchtransferline.updateBatchcount(); // remove may throw exception
lEntityManager.getTransaction().commit();

// close shop
lEntityManager.close();
lEntityManagerFactory.close();

Causes:

Exception in thread "main" java.lang.IllegalArgumentException: Entity must be managed to call remove: nl.reinders.bm.Batchcount@94cc7, Batchcountnr=1330178, try merging the detached and try the remove again.
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.per formRemove(UnitOfWorkImpl.java:3251)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.remov e(EntityManagerImpl.java:283)
at nl.reinders.bm.Batchcount.changeAllocationTo(Batchcount.java :97)
at nl.reinders.bm.Batchtransferline.updateBatchcount(Batchtrans ferline.java:92)
at nl.reinders.bm.BMTestToplink.main(BMTestToplink.java:68)

In this remove:

// delete the batchcount
lBatchcount.setFromAmountBatchtransferline(null);
lBatchcount.setBatch(null);
lEntityManager.merge(lBatchcount);
lEntityManager.remove(lBatchcount);

The EM class that is being printed is: org.eclipse.persistence.internal.jpa.EntityManagerImpl
Re: Entity must be managed to call remove [message #384210 is a reply to message #384209] Sat, 29 November 2008 14:50 Go to previous messageGo to next message
Doug Clarke is currently offline Doug ClarkeFriend
Messages: 155
Registered: July 2009
Senior Member
The EntityManager's merge call will return to you the managed entity. Make
sure you use this instance in the subsequent remove call.

http://java.sun.com/javaee/5/docs/api/javax/persistence/Enti tyManager.html#merge(T)

Doug
Re: Entity must be managed to call remove [message #384212 is a reply to message #384210] Wed, 03 December 2008 14:00 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 807
Registered: July 2009
Senior Member
Yes, that solved the exception - stupid mistake again. Sorry.

However I still have the problem that changes made in the PrePersist hook are not committed. Below once again the store logic in the generic entity manager:

preSave(); //<-------
EntityManagerExtender.executeNextClearWithoutClearingRemoved Entities(lEntityManager); // if we're using EntityManagerExtender (which we should)...
lEntityManager.clear(); // prevent errors from a previous store session (not rollbacked optimistic lock increments) to screw things up
lEntityManager.getTransaction().begin();
duringSavePreMerge(); //<-------
T lMergedEntity = lEntityManager.merge(getEntity());
duringSavePostMerge(lMergedEntity); //<-------
lEntityManager.getTransaction().commit();
postSave(lMergedEntity); //<-------

I've marked four lines (<---) that allow listeners to act upon events by the manager, quite similar to @PrePersist.

Now, if I hook into the "duringSavePostMerge" with the code below:

@Override public void duringSavePostMerge(Batchtransfer e)
{
for (Batchtransferline lBatchtransferline : e.getBatchtransferlinesWhereIAmBatchtransfer())
{
lBatchtransferline.updateBatchcount();
}
}


Then the entities created or altered by "updateBatchcount" are nicely persisted. However, if I hook into Batchtransferline's @PrePersist using Eclipselink with:

@PrePersist @PreUpdate
public void preSave()
{
...
preSaveHook();
}

@Override public void preSaveHook()
{
super.preSaveHook();
System.out.println("!!!!!@PrePersist event");
updateBatchcount();
}


I get EXACTLY the same modifications on the business model, even the sequences are modified, the only difference being that the created entities never actually stored. The @PrePersist is executed as part of the commit.

Any ideas why? I would prefer the BM to handle the creation of related entities internally, and not via an application layer event.

Tom
Re: Entity must be managed to call remove [message #384213 is a reply to message #384212] Wed, 03 December 2008 14:47 Go to previous messageGo to next message
James Sutherland is currently offline James SutherlandFriend
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

Try doing a persist before the commit.

lEntityManager.persist(lMergedEntity);

What does the updateBatchcount() do, does it create new objects or just
change existing ones?

---
James
http://www.nabble.com/EclipseLink---Users-f26658.html


James : Wiki : Book : Blog : Twitter
Re: Entity must be managed to call remove [message #384214 is a reply to message #384213] Wed, 03 December 2008 15:25 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 807
Registered: July 2009
Senior Member
> What does the updateBatchcount() do, does it create new objects or just
> change existing ones?

Basically it modifies the underlying stock. So it may create new allocations, or modify them, or remove them.

Tom
Re: Entity must be managed to call remove [message #384215 is a reply to message #384213] Wed, 03 December 2008 15:51 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 807
Registered: July 2009
Senior Member
> Try doing a persist before the commit.

No difference. For your comparison, this is the SQL that happens on the application event:

....
2008-12-03 10:32:47,390 DEBUG nl.reinders.bm.Batchcount.changeContibutionTo(Batchcount.jav a:329) changeContibutionTo done
2008-12-03 10:32:47,515 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #13778707: [1] setTimestamp=2008-12-03 10:32:47.156 / java.sql.Timestamp / UPDATE batch SET dwhmodified = >>>HERE<<< , lazylock = ? WHERE ((batchnr = ?) AND (lazylock = ?))
2008-12-03 10:32:47,531 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #13778707: [2] setLong=40 / java.lang.Long / UPDATE batch SET dwhmodified = ?, lazylock = >>>HERE<<< WHERE ((batchnr = ?) AND (lazylock = ?))
2008-12-03 10:32:47,562 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #13778707: [3] setBigDecimal=11428 / java.math.BigDecimal / UPDATE batch SET dwhmodified = ?, lazylock = ? WHERE ((batchnr = >>>HERE<<< ) AND (lazylock = ?))
2008-12-03 10:32:47,578 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #13778707: [4] setInt=39 / java.lang.Integer / UPDATE batch SET dwhmodified = ?, lazylock = ? WHERE ((batchnr = ?) AND (lazylock = >>>HERE<<< ))
2008-12-03 10:32:47,703 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #13778707: executeUpdate: UPDATE batch SET dwhmodified = ?, lazylock = ? WHERE ((batchnr = ?) AND (lazylock = ?))
2008-12-03 10:32:47,734 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #17255007: [1] setBigDecimal=110 / java.math.BigDecimal / UPDATE batchtransferline SET from_amount = >>>HERE<<< , dwhmodified = ?, lazylock = ? WHERE ((batchtransferlinenr = ?) AND (lazylock = ?))
2008-12-03 10:32:47,734 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #17255007: [2] setTimestamp=2008-12-03 10:32:47.0 / java.sql.Timestamp / UPDATE batchtransferline SET from_amount = ?, dwhmodified = >>>HERE<<< , lazylock = ? WHERE ((batchtransferlinenr = ?) AND (lazylock = ?))
2008-12-03 10:32:47,734 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #17255007: [3] setLong=54 / java.lang.Long / UPDATE batchtransferline SET from_amount = ?, dwhmodified = ?, lazylock = >>>HERE<<< WHERE ((batchtransferlinenr = ?) AND (lazylock = ?))
2008-12-03 10:32:47,734 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #17255007: [4] setBigDecimal=18 / java.math.BigDecimal / UPDATE batchtransferline SET from_amount = ?, dwhmodified = ?, lazylock = ? WHERE ((batchtransferlinenr = >>>HERE<<< ) AND (lazylock = ?))
2008-12-03 10:32:47,734 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #17255007: [5] setInt=53 / java.lang.Integer / UPDATE batchtransferline SET from_amount = ?, dwhmodified = ?, lazylock = ? WHERE ((batchtransferlinenr = ?) AND (lazylock = >>>HERE<<< ))
2008-12-03 10:32:47,734 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #17255007: executeUpdate: UPDATE batchtransferline SET from_amount = ?, dwhmodified = ?, lazylock = ? WHERE ((batchtransferlinenr = ?) AND (lazylock = ?))
2008-12-03 10:32:47,781 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #31617140: [1] setBigDecimal=1330191 / java.math.BigDecimal / INSERT IGNORE INTO batchcount (batchcountnr, batchdate, amount, description, rollentodolinenr, rollendonelinenr, lazylock, dwhmodified, dwhby, batchnr, to_amount_batchtransferlinenr, from_amount_batchtransferlinenr) VALUES ( >>>HERE<<< , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2008-12-03 10:32:47,781 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #31617140: [2] setNull=91 / java.lang.Integer / INSERT IGNORE INTO batchcount (batchcountnr, batchdate, amount, description, rollentodolinenr, rollendonelinenr, lazylock, dwhmodified, dwhby, batchnr, to_amount_batchtransferlinenr, from_amount_batchtransferlinenr) VALUES (?, >>>HERE<<< , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2008-12-03 10:32:47,781 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #31617140: [3] setBigDecimal=-60 / java.math.BigDecimal / INSERT IGNORE INTO batchcount (batchcountnr, batchdate, amount, description, rollentodolinenr, rollendonelinenr, lazylock, dwhmodified, dwhby, batchnr, to_amount_batchtransferlinenr, from_amount_batchtransferlinenr) VALUES (?, ?, >>>HERE<<< , ?, ?, ?, ?, ?, ?, ?, ?, ?)
2008-12-03 10:32:47,781 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #31617140: [4] setNull=12 / java.lang.Integer / INSERT IGNORE INTO batchcount (batchcountnr, batchdate, amount, description, rollentodolinenr, rollendonelinenr, lazylock, dwhmodified, dwhby, batchnr, to_amount_batchtransferlinenr, from_amount_batchtransferlinenr) VALUES (?, ?, ?, >>>HERE<<< , ?, ?, ?, ?, ?, ?, ?, ?)
2008-12-03 10:32:47,781 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #31617140: [5] setNull=4 / java.lang.Integer / INSERT IGNORE INTO batchcount (batchcountnr, batchdate, amount, description, rollentodolinenr, rollendonelinenr, lazylock, dwhmodified, dwhby, batchnr, to_amount_batchtransferlinenr, from_amount_batchtransferlinenr) VALUES (?, ?, ?, ?, >>>HERE<<< , ?, ?, ?, ?, ?, ?, ?)
2008-12-03 10:32:47,781 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #31617140: [6] setNull=4 / java.lang.Integer / INSERT IGNORE INTO batchcount (batchcountnr, batchdate, amount, description, rollentodolinenr, rollendonelinenr, lazylock, dwhmodified, dwhby, batchnr, to_amount_batchtransferlinenr, from_amount_batchtransferlinenr) VALUES (?, ?, ?, ?, ?, >>>HERE<<< , ?, ?, ?, ?, ?, ?)
2008-12-03 10:32:47,781 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #31617140: [7] setLong=1 / java.lang.Long / INSERT IGNORE INTO batchcount (batchcountnr, batchdate, amount, description, rollentodolinenr, rollendonelinenr, lazylock, dwhmodified, dwhby, batchnr, to_amount_batchtransferlinenr, from_amount_batchtransferlinenr) VALUES (?, ?, ?, ?, ?, ?, >>>HERE<<< , ?, ?, ?, ?, ?)
2008-12-03 10:32:47,781 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #31617140: [8] setTimestamp=2008-12-03 10:32:47.156 / java.sql.Timestamp / INSERT IGNORE INTO batchcount (batchcountnr, batchdate, amount, description, rollentodolinenr, rollendonelinenr, lazylock, dwhmodified, dwhby, batchnr, to_amount_batchtransferlinenr, from_amount_batchtransferlinenr) VALUES (?, ?, ?, ?, ?, ?, ?, >>>HERE<<< , ?, ?, ?, ?)
2008-12-03 10:32:47,781 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #31617140: [9] setBigDecimal=24 / java.math.BigDecimal / INSERT IGNORE INTO batchcount (batchcountnr, batchdate, amount, description, rollentodolinenr, rollendonelinenr, lazylock, dwhmodified, dwhby, batchnr, to_amount_batchtransferlinenr, from_amount_batchtransferlinenr) VALUES (?, ?, ?, ?, ?, ?, ?, ?, >>>HERE<<< , ?, ?, ?)
2008-12-03 10:32:47,796 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #31617140: [10] setBigDecimal=11428 / java.math.BigDecimal / INSERT IGNORE INTO batchcount (batchcountnr, batchdate, amount, description, rollentodolinenr, rollendonelinenr, lazylock, dwhmodified, dwhby, batchnr, to_amount_batchtransferlinenr, from_amount_batchtransferlinenr) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, >>>HERE<<< , ?, ?)
2008-12-03 10:32:47,796 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #31617140: [11] setNull=4 / java.lang.Integer / INSERT IGNORE INTO batchcount (batchcountnr, batchdate, amount, description, rollentodolinenr, rollendonelinenr, lazylock, dwhmodified, dwhby, batchnr, to_amount_batchtransferlinenr, from_amount_batchtransferlinenr) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, >>>HERE<<< , ?)
2008-12-03 10:32:47,796 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #31617140: [12] setBigDecimal=18 / java.math.BigDecimal / INSERT IGNORE INTO batchcount (batchcountnr, batchdate, amount, description, rollentodolinenr, rollendonelinenr, lazylock, dwhmodified, dwhby, batchnr, to_amount_batchtransferlinenr, from_amount_batchtransferlinenr) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, >>>HERE<<< )
2008-12-03 10:32:48,171 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #31617140: executeUpdate: INSERT IGNORE INTO batchcount (batchcountnr, batchdate, amount, description, rollentodolinenr, rollendonelinenr, lazylock, dwhmodified, dwhby, batchnr, to_amount_batchtransferlinenr, from_amount_batchtransferlinenr) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

There are 3 SQLs
1. update the BATCH
2. update the BATCHTRANSFERLINE (from 50 to 110, so a delta of 60)
3. insert a BATCHCOUNT (allocate that 60)

The change causing SQL 2 is made by the user, and SQL 1 and 3 and the result of the event code.

And this is done when using @PrePersist:

....
2008-12-03 10:30:26,562 DEBUG nl.reinders.bm.Batchcount.changeContibutionTo(Batchcount.jav a:329) changeContibutionTo done
2008-12-03 10:30:26,593 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #17256714: [1] setBigDecimal=110 / java.math.BigDecimal / UPDATE batchtransferline SET from_amount = >>>HERE<<< , dwhmodified = ?, lazylock = ? WHERE ((batchtransferlinenr = ?) AND (lazylock = ?))
2008-12-03 10:30:26,593 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #17256714: [2] setTimestamp=2008-12-03 10:30:11.031 / java.sql.Timestamp / UPDATE batchtransferline SET from_amount = ?, dwhmodified = >>>HERE<<< , lazylock = ? WHERE ((batchtransferlinenr = ?) AND (lazylock = ?))
2008-12-03 10:30:26,609 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #17256714: [3] setLong=52 / java.lang.Long / UPDATE batchtransferline SET from_amount = ?, dwhmodified = ?, lazylock = >>>HERE<<< WHERE ((batchtransferlinenr = ?) AND (lazylock = ?))
2008-12-03 10:30:26,640 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #17256714: [4] setBigDecimal=18 / java.math.BigDecimal / UPDATE batchtransferline SET from_amount = ?, dwhmodified = ?, lazylock = ? WHERE ((batchtransferlinenr = >>>HERE<<< ) AND (lazylock = ?))
2008-12-03 10:30:26,640 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #17256714: [5] setInt=51 / java.lang.Integer / UPDATE batchtransferline SET from_amount = ?, dwhmodified = ?, lazylock = ? WHERE ((batchtransferlinenr = ?) AND (lazylock = >>>HERE<<< ))
2008-12-03 10:30:26,687 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #17256714: executeUpdate: UPDATE batchtransferline SET from_amount = ?, dwhmodified = ?, lazylock = ? WHERE ((batchtransferlinenr = ?) AND (lazylock = ?))

Only SQL number 2 is present.

For completeness the testcode:

// increment (causing an insert)
Batchtransferline lBatchtransferline = Batchtransferline.findByPK(18);
lBatchtransferline.setFromAmount(BigInteger.valueOf(100));

// commit
EntityManagerExtender.executeNextClearWithoutClearingRemoved Entities(lEntityManager); // if we're using EntityManagerExtender (which we should)...
lEntityManager.clear(); // prevent errors from a previous store session (not rollbacked optimistic lock increments) to screw things up
lEntityManager.getTransaction().begin();
lBatchtransferline = lEntityManager.merge(lBatchtransferline);
lEntityManager.persist(lBatchtransferline);
//lBatchtransferline.updateBatchcount(); // emulate application event
lEntityManager.getTransaction().commit();

System.out.println(" ------------------------------------------------------------ ---------------------- ");

// decrement (causing a remove)
lBatchtransferline = Batchtransferline.findByPK(18);
lBatchtransferline.setFromAmount(BigInteger.valueOf(50));

// commit
EntityManagerExtender.executeNextClearWithoutClearingRemoved Entities(lEntityManager); // if we're using EntityManagerExtender (which we should)...
lEntityManager.clear(); // prevent errors from a previous store session (not rollbacked optimistic lock increments) to screw things up
lEntityManager.getTransaction().begin();
lBatchtransferline = lEntityManager.merge(lBatchtransferline);
lEntityManager.persist(lBatchtransferline);
//lBatchtransferline.updateBatchcount(); // emulate application event
lEntityManager.getTransaction().commit();
Re: Entity must be managed to call remove [message #384220 is a reply to message #384215] Thu, 04 December 2008 14:14 Go to previous messageGo to next message
James Sutherland is currently offline James SutherlandFriend
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

I suppose making changes and adding new objects from within change events
is not really a good idea. The issue seems to be if you do not
persist/trigger the events before the commit, then they are not trigger
until the commit in the middle of the process that is auto-persisting new
objects, but this process has already process some of the objects that you
are changing, so it is really too late to be changing objects in this way.

So, if you ensure the events fire before commit, by calling persist on the
object with the persist event before commit (or ensure the persist will
cascade to this object). If you fire the events before commit, you should
be ok.

You could also try to call EntityManager.persist from within your
prePersist method, but updates will still be an issue depending on your
change policy.

---
James
http://www.nabble.com/EclipseLink---Users-f26658.html


James : Wiki : Book : Blog : Twitter
Re: Entity must be managed to call remove [message #384230 is a reply to message #384220] Thu, 04 December 2008 15:20 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 807
Registered: July 2009
Senior Member
> I suppose making changes and adding new objects from within change
> events is not really a good idea. The issue seems to be if you do not
> persist/trigger the events before the commit, then they are not trigger
> until the commit in the middle of the process that is auto-persisting
> new objects, but this process has already process some of the objects
> that you are changing, so it is really too late to be changing objects
> in this way.

I understand. However, then the capability of the @PrePersist event is severely reduced. For what is the event intended? Only update simple and internal properties?



> So, if you ensure the events fire before commit, by calling persist on
> the object with the persist event before commit (or ensure the persist
> will cascade to this object). If you fire the events before commit, you
> should be ok.

For all means and purposes, my application level event is the same as @PrePersist, it only is triggered before the commit (as you suggest here).

Wouldn't it be a better idea to first fire the @PrePersist events on all objects first and then start really persist them? So really PRE persist and not somewhere inside the persist logic?

Again, I do not like the BM to be dependent on an trigger that is controller one layer up.

Would it be possible to register a listener on the EntityManager and fire an event upon executing the commit method?
Hmmm. AspectJ could do catch that... And I already confirmed that it can be combined with Eclipselink. Hm. Hm. Have to think about that one.



> You could also try to call EntityManager.persist from within your
> prePersist method, but updates will still be an issue depending on your
> change policy.

I already do a persist on the newly created Batchcount entity. So that won't work. Is there a way to force that entity into the persist logic?

Tom
Re: Entity must be managed to call remove [message #384233 is a reply to message #384230] Mon, 08 December 2008 14:01 Go to previous message
James Sutherland is currently offline James SutherlandFriend
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

You may wish to look into the SessionEvent preCommitUnitOfWork, this will
be called before commit begins any processing. You can register a
SessionEventListener in the persistence.xml
("eclipselink.session-event-listener"), or directly on an EntityManager's
active Session.


James : Wiki : Book : Blog : Twitter
Previous Topic:Yikes! ConcurrentModificationException
Next Topic:Eclipselink not picking up database changes on refresh
Goto Forum:
  


Current Time: Thu Nov 27 22:27:06 GMT 2014

Powered by FUDForum. Page generated in 0.02982 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software