Home » Eclipse Projects » EclipseLink » Entity must be managed to call remove
Entity must be managed to call remove [message #383827] |
Thu, 27 November 2008 04:55  |
Eclipse User |
|
|
|
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 #384215 is a reply to message #384213] |
Wed, 03 December 2008 10:51   |
Eclipse User |
|
|
|
> 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 #384230 is a reply to message #384220] |
Thu, 04 December 2008 10:20   |
Eclipse User |
|
|
|
> 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 09:01  |
Eclipse User |
|
|
|
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.
|
|
|
Goto Forum:
Current Time: Wed Jul 23 15:48:46 EDT 2025
Powered by FUDForum. Page generated in 0.06022 seconds
|