Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » change then remove results in exception... why
change then remove results in exception... why [message #386072] Fri, 27 March 2009 09:13 Go to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 807
Registered: July 2009
Senior Member
Consider the following scenarion (in my standalone fat client, so it is not using burst database changes): an entity is fetched from the database, then a change is made to the entity (making it actually invalid to be stored in the database) and then the entity is removed. Below is a small test case.

// entitymanagerfactory
EntityManagerFactory lEntityManagerFactory = ...

// entitymanager
EntityManager lEntityManager = lEntityManagerFactory.createEntityManager();

// emulate user entry
Article2Storage lArticle2Storage = Article2Storage.findByPK(229277);
lArticle2Storage.setArticle(null); // this is not allowed, a N-M record must have both keys
lEntityManager.remove(lArticle2Storage); // now remove it

// commit
lEntityManager.getTransaction().begin();
lEntityManager.getTransaction().commit();

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


This results in the following exception:

2009-03-27 10:00:57,296 DEBUG org.tbee.util.jdbc.PreparedStatement.invoke(PreparedStatemen t.java:139) #14992216[C24016891]: executeUpdate: UPDATE article2storage SET articlenr = ?, dwhmodified = ?, dwhby = ?, lazylock = ? WHERE ((oidnr = ?) AND (lazylock = ?))
[EL Warning]: 2009.03.27 10:00:57.578--UnitOfWork(25928160)--Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 1.0.2 (Build 20081024)): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Cannot insert a null into column (article2storage.articlenr).
Error Code: -391
Call: UPDATE article2storage SET articlenr = ?, dwhmodified = ?, dwhby = ?, lazylock = ? WHERE ((oidnr = ?) AND (lazylock = ?))
bind => [null, 2009-03-27 10:00:38.984, 1, 2, 229277, 1]
Query: UpdateObjectQuery(nl.reinders.bm.Article2Storage@198f2a6, Oidnr=229277)
at org.eclipse.persistence.exceptions.DatabaseException.sqlExce ption(DatabaseException.java:313)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAcce ssor.executeDirectNoSelect(DatabaseAccessor.java:757)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAcce ssor.executeNoSelect(DatabaseAccessor.java:823)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAcce ssor.basicExecuteCall(DatabaseAccessor.java:557)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAcce ssor.executeCall(DatabaseAccessor.java:500)
at org.eclipse.persistence.internal.sessions.AbstractSession.ex ecuteCall(AbstractSession.java:855)
at org.eclipse.persistence.internal.sessions.IsolatedClientSess ion.executeCall(IsolatedClientSession.java:132)
at org.eclipse.persistence.internal.queries.DatasourceCallQuery Mechanism.executeCall(DatasourceCallQueryMechanism.java:204)
at org.eclipse.persistence.internal.queries.DatasourceCallQuery Mechanism.executeCall(DatasourceCallQueryMechanism.java:190)
at org.eclipse.persistence.internal.queries.DatasourceCallQuery Mechanism.updateObject(DatasourceCallQueryMechanism.java:681 )
at org.eclipse.persistence.internal.queries.StatementQueryMecha nism.updateObject(StatementQueryMechanism.java:431)
at org.eclipse.persistence.internal.queries.DatabaseQueryMechan ism.updateObjectForWriteWithChangeSet(DatabaseQueryMechanism .java:1142)
at org.eclipse.persistence.queries.UpdateObjectQuery.executeCom mitWithChangeSet(UpdateObjectQuery.java:84)
at org.eclipse.persistence.internal.queries.DatabaseQueryMechan ism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:29 0)
at org.eclipse.persistence.queries.WriteObjectQuery.executeData baseQuery(WriteObjectQuery.java:58)
at org.eclipse.persistence.queries.DatabaseQuery.execute(Databa seQuery.java:666)
at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitO fWork(DatabaseQuery.java:585)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.execu teInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery. java:114)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.execu teInUnitOfWork(ObjectLevelModifyQuery.java:86)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.int ernalExecuteQuery(UnitOfWorkImpl.java:2587)
at org.eclipse.persistence.internal.sessions.AbstractSession.ex ecuteQuery(AbstractSession.java:1178)
at org.eclipse.persistence.internal.sessions.AbstractSession.ex ecuteQuery(AbstractSession.java:1162)
at org.eclipse.persistence.internal.sessions.AbstractSession.ex ecuteQuery(AbstractSession.java:1108)
at org.eclipse.persistence.internal.sessions.CommitManager.comm itChangedObjectsForClassWithChangeSet(CommitManager.java:297 )
at org.eclipse.persistence.internal.sessions.CommitManager.comm itAllObjectsForClassWithChangeSet(CommitManager.java:228)
at org.eclipse.persistence.internal.sessions.CommitManager.comm itAllObjectsWithChangeSet(CommitManager.java:185)
at org.eclipse.persistence.internal.sessions.AbstractSession.wr iteAllObjectsWithChangeSet(AbstractSession.java:3129)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.com mitToDatabase(UnitOfWorkImpl.java:1241)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUni tOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:478)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.com mitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1330)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUni tOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java: 159)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.com mitAndResume(UnitOfWorkImpl.java:1002)
at org.eclipse.persistence.internal.jpa.transaction.EntityTrans actionImpl.commitInternal(EntityTransactionImpl.java:84)
at org.eclipse.persistence.internal.jpa.transaction.EntityTrans actionImpl.commit(EntityTransactionImpl.java:63)
at nl.reinders.bm.BMTestToplink.main(BMTestToplink.java:116)


As it turns out, even though entity has been removed, the change is still being persisted. I'm a bit uncertain about this. On the one hand I can imagine that Eclipselink simply keeps a list of changes and executes them. On the other hand, AFAIK that is not the case, but a copied model is created. If N-M entity was removed, there is no use in persisting it.

Even if I remove both key-entities, making the entity unreachable for persistence-via-relation, the exception remains:

// emulate user entry
Article2Storage lArticle2Storage = Article2Storage.findByPK(229277);
lArticle2Storage.setArticle(null);
lArticle2Storage.setStorage(null);
lEntityManager.remove(lArticle2Storage);

So the question: if an entity is removed, why are changes to it still persisted?
Re: change then remove results in exception... why [message #386073 is a reply to message #386072] Fri, 27 March 2009 09:29 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 807
Registered: July 2009
Senior Member
A small addition to why this scenario is happening: in my fat client, when a delete is made, the in-memory change is asynchronous from the database change.

That means that when the entity is removed in the JList or JTable, that is reflected in the underlying entities; in this case the article2storage is removed from the list in article, and the reference back (this is a two-way reference setup) is nullified. Now the JList is refreshed and the article2storage is gone. Later on, when the user presses "save", these changes are persisted.
Re: change then remove results in exception... why [message #386077 is a reply to message #386072] Mon, 30 March 2009 14:04 Go to previous messageGo to next message
James Sutherland is currently offline James SutherlandFriend
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

The main reason for updating an object before deleting it is that this is
sometimes required. If your object has a constraint or dependency on
another object, if must be updated in order to be deleted. So, we must
allow an object to be updated before deletion.

In could be possible to make this a configurable option, so if you think
you never need to update an object being deleted run could set this
option, so you may wish to log an enhancement request for this. We do
already have the existing option "perform deletes first" which has a
similar effect. However, in general it is best if you do not change any
objects that you do not want updated, then you will have no issues.

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


James : Wiki : Book : Blog : Twitter
Re: change then remove results in exception... why [message #386079 is a reply to message #386077] Mon, 30 March 2009 15:32 Go to previous message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 807
Registered: July 2009
Senior Member
> In could be possible to make this a configurable option, so if you think
> you never need to update an object being deleted run could set this
> option, so you may wish to log an enhancement request for this. We do
> already have the existing option "perform deletes first" which has a
> similar effect. However, in general it is best if you do not change any
> objects that you do not want updated, then you will have no issues.

I cannot force the user these constraints; he may first change an object, then delete it.

For now I have solve this using deferred constraints, but I'll try that perform delete first option.

Tom
Previous Topic:force the connection
Next Topic:Need help configuring EclipseLink JPA
Goto Forum:
  


Current Time: Wed Nov 26 05:48:53 GMT 2014

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

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