-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Insert Before Delete causes Contraint Violation in Database
PostPosted: Wed Aug 24, 2005 2:27 am 
Newbie

Joined: Wed Aug 24, 2005 1:08 am
Posts: 8
I am using the long session model, where I open a session query my data, disconnect the session, let the user make a bunch of changes, then reconnect the session and session.update(object).
The problem i have is that if a user removes one of the rows for the Defaultfactories collection and then adds a new row, Hiberate will Insert the new record and then Delete the old one. This usually works fine except that in this case, the new Row has some of the same values as the old row, and causes a constrain violation in the database, because the old row has not been deleted yet.

Is there a way to tell hibernate to delete rows before inserting new ones?

Thanks
Dave

Hibernate version:
3

Mapping documents:
<hibernate-mapping package="beans">
<class
name="Projectheader"
table="PROJECTHEADER"
>
<id
name="Projectid"
column="PROJECTID"
type="string"

/>

...

<bag
name="Defaultfactories"
table="PROJECTDEFAULTFACTORIES"
cascade="all,delete-orphan"
inverse="true"
>
<key column="ID_Project" not-null="true"/>
<one-to-many class="Projectdefaultfactories" />
</bag>
</class>
</hibernate-mapping>



<hibernate-mapping package="beans">
<class
name="Projectdefaultfactories"
table="PROJECTDEFAULTFACTORIES"
>
<id
name="IdDefaultfactorymap"
column="ID_DEFAULTFACTORYMAP"
type="java.lang.Long"
>
<generator class="identity"/>
</id>

...

<many-to-one
name="Project"
column="ID_PROJECT"
not-null="true"
cascade="none"
class="Projectheader"
/>
</class>
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():
//Query Record
session.disconnect();
//Remove Row from sub collection
//Add row to sub Collection (new row has contraint violation with removed row)
session.reconnect();
tx=session.beginTransaction();
session.update(object);
tx.commit();
session.close();

Full stack trace of any exception that occurs:
[24/08/05 15:17:01:283 EST] 1aef1aef SystemErr R org.hibernate.exception.ConstraintViolationException: could not insert: [beans.Projectdefaultfactories]
at java.lang.Throwable.<init>(Throwable.java:59)
at java.lang.Throwable.<init>(Throwable.java:73)
at org.hibernate.exception.NestableRuntimeException.<init>(NestableRuntimeException.java:124)
at org.hibernate.JDBCException.<init>(JDBCException.java:20)
at org.hibernate.JDBCException.<init>(JDBCException.java:25)
at org.hibernate.exception.ConstraintViolationException.<init>(ConstraintViolationException.java:24)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:63)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:1790)
at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:2192)
at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:34)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:238)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:158)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:104)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:184)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:173)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:96)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:69)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:416)
at org.hibernate.engine.Cascades$5.cascade(Cascades.java:153)
at org.hibernate.engine.Cascades.cascade(Cascades.java:721)
at org.hibernate.engine.Cascades.cascadeCollection(Cascades.java:860)
at org.hibernate.engine.Cascades.cascade(Cascades.java:739)
at org.hibernate.engine.Cascades.cascade(Cascades.java:817)
at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:121)
at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:112)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:59)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:675)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:298)
at org.hibernate.transaction.JTATransaction.commit(JTATransaction.java:112)
at TableEditor.HibernateSessionManager.disconnectSession(HibernateSessionManager.java:101)
at TableEditor.DataManager.disconnectHibernateSession(DataManager.java:85)
at TableEditor.EditorController.updateRecordFromRequest(EditorController.java:508)
at TableEditor.EditorController.preformDoPostAction(EditorController.java:393)
at TableEditor.EditorController.doPost(EditorController.java:355)
at quotes.ProjectsServlet.doPost(ProjectsServlet.java:57)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at com.ibm.ws.webcontainer.servlet.StrictServletInstance.doService(StrictServletInstance.java:110)
at com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet._service(StrictLifecycleServlet.java:174)
at com.ibm.ws.webcontainer.servlet.IdleServletState.service(StrictLifecycleServlet.java:313)
at com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet.service(StrictLifecycleServlet.java:116)
at com.ibm.ws.webcontainer.servlet.ServletInstance.service(ServletInstance.java:283)
at com.ibm.ws.webcontainer.servlet.ValidServletReferenceState.dispatch(ValidServletReferenceState.java:42)
at com.ibm.ws.webcontainer.servlet.ServletInstanceReference.dispatch(ServletInstanceReference.java:40)
at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.handleWebAppDispatch(WebAppRequestDispatcher.java:1019)
at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.dispatch(WebAppRequestDispatcher.java:592)
at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java:204)
at com.ibm.ws.webcontainer.srt.WebAppInvoker.doForward(WebAppInvoker.java:125)
at com.ibm.ws.webcontainer.srt.WebAppInvoker.handleInvocationHook(WebAppInvoker.java:286)
at com.ibm.ws.webcontainer.cache.invocation.CachedInvocation.handleInvocation(CachedInvocation.java:71)
at com.ibm.ws.webcontainer.cache.invocation.CacheableInvocationContext.invoke(CacheableInvocationContext.java:116)
at com.ibm.ws.webcontainer.srp.ServletRequestProcessor.dispatchByURI(ServletRequestProcessor.java:186)
at com.ibm.ws.webcontainer.oselistener.OSEListenerDispatcher.service(OSEListener.java:334)
at com.ibm.ws.webcontainer.http.HttpConnection.handleRequest(HttpConnection.java:56)
at com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection.java:615)
at com.ibm.ws.http.HttpConnection.run(HttpConnection.java:449)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:912)
Caused by: com.ibm.websphere.ce.cm.DuplicateKeyException: [IBM][CLI Driver][DB2/NT] SQL0803N One or more values in the INSERT statement, UPDATE statement, or foreign key update caused by a DELETE statement are not valid because the primary key, unique constraint or unique index identified by "1" constrains table "QUOTES.PROJECTDEFAULTFACTORIES" from having duplicate rows for those columns. SQLSTATE=23505

at java.lang.Throwable.<init>(Throwable.java:59)
at java.lang.Throwable.<init>(Throwable.java:73)
at java.sql.SQLException.<init>(SQLException.java:53)
at com.ibm.websphere.ce.cm.PortableSQLException.<init>(PortableSQLException.java:38)
at com.ibm.websphere.ce.cm.DuplicateKeyException.<init>(DuplicateKeyException.java:31)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:80)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:44)
at java.lang.reflect.Constructor.newInstance(Constructor.java)
at com.ibm.websphere.rsadapter.GenericDataStoreHelper.mapExceptionHelper(GenericDataStoreHelper.java:474)
at com.ibm.websphere.rsadapter.GenericDataStoreHelper.mapException(GenericDataStoreHelper.java:517)
at com.ibm.ws.rsadapter.jdbc.WSJdbcUtil.mapException(WSJdbcUtil.java:826)
at com.ibm.ws.rsadapter.jdbc.WSJdbcPreparedStatement.executeUpdate(WSJdbcPreparedStatement.java:482)
at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:1780)
at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:2192)
at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:34)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:238)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:158)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:104)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:184)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:173)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:96)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:69)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:416)
at org.hibernate.engine.Cascades$5.cascade(Cascades.java:153)
at org.hibernate.engine.Cascades.cascade(Cascades.java:721)
at org.hibernate.engine.Cascades.cascadeCollection(Cascades.java:860)
at org.hibernate.engine.Cascades.cascade(Cascades.java:739)
at org.hibernate.engine.Cascades.cascade(Cascades.java:817)
at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:121)
at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:112)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:59)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:675)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:298)
at org.hibernate.transaction.JTATransaction.commit(JTATransaction.java:112)
at TableEditor.HibernateSessionManager.disconnectSession(HibernateSessionManager.java:101)
at TableEditor.DataManager.disconnectHibernateSession(DataManager.java:85)
at TableEditor.EditorController.updateRecordFromRequest(EditorController.java:508)
at TableEditor.EditorController.preformDoPostAction(EditorController.java:393)
at TableEditor.EditorController.doPost(EditorController.java:355)
at quotes.ProjectsServlet.doPost(ProjectsServlet.java:57)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at com.ibm.ws.webcontainer.servlet.StrictServletInstance.doService(StrictServletInstance.java:110)
at com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet._service(StrictLifecycleServlet.java:174)
at com.ibm.ws.webcontainer.servlet.IdleServletState.service(StrictLifecycleServlet.java:313)
at com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet.service(StrictLifecycleServlet.java:116)
at com.ibm.ws.webcontainer.servlet.ServletInstance.service(ServletInstance.java:283)
at com.ibm.ws.webcontainer.servlet.ValidServletReferenceState.dispatch(ValidServletReferenceState.java:42)
at com.ibm.ws.webcontainer.servlet.ServletInstanceReference.dispatch(ServletInstanceReference.java:40)
at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.handleWebAppDispatch(WebAppRequestDispatcher.java:1019)
at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.dispatch(WebAppRequestDispatcher.java:592)
at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java:204)
at com.ibm.ws.webcontainer.srt.WebAppInvoker.doForward(WebAppInvoker.java:125)
at com.ibm.ws.webcontainer.srt.WebAppInvoker.handleInvocationHook(WebAppInvoker.java:286)
at com.ibm.ws.webcontainer.cache.invocation.CachedInvocation.handleInvocation(CachedInvocation.java:71)
at com.ibm.ws.webcontainer.cache.invocation.CacheableInvocationContext.invoke(CacheableInvocationContext.java:116)
at com.ibm.ws.webcontainer.srp.ServletRequestProcessor.dispatchByURI(ServletRequestProcessor.java:186)
at com.ibm.ws.webcontainer.oselistener.OSEListenerDispatcher.service(OSEListener.java:334)
at com.ibm.ws.webcontainer.http.HttpConnection.handleRequest(HttpConnection.java:56)
at com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection.java:615)
at com.ibm.ws.http.HttpConnection.run(HttpConnection.java:449)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:912)

Name and version of the database you are using:
DB2 8.1
The generated SQL (show_sql=true):
insert into Quotes.PROJECTDEFAULTFACTORIES (ID_FACTORY, ID_PROJECT, ID_Contact, ID_DEFAULTFACTORYMAP) values (?, ?, ?, default)


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 24, 2005 1:19 pm 
Expert
Expert

Joined: Fri Aug 19, 2005 2:11 pm
Posts: 628
Location: Cincinnati
its the whole persistence thing.

force hibernate to perform the delete before it moves on.
session.flush() should do the trick, then maybe a session.refresh() to make sure the database is the same as the in memory instantiation of it


Top
 Profile  
 
 Post subject: Disconnected Session- incorrect order of operation
PostPosted: Thu Aug 25, 2005 12:25 am 
Newbie

Joined: Wed Aug 24, 2005 1:08 am
Posts: 8
Sorry, i messed up my term there. I am using the Disconnected Session Model. I use one session to Load the dataobject. Then allow the user multiple user transactions to modify the data. When they are ready to save i open a new session and session.update()

Hibernate is trying to persist the data, but the order it preforms the opperations is incorrect. Its causing a contraint violation by trying to insert before it deletes.

I have tried keeping the 1st session and just .disconnect() after querying, then when ready to save .reconnect() .update() .flush() But hibernate still does the same thing.

I have reviewed a Hibernate book and it lists the order of operations as
1. Entity Insertion
2. Entity Updates
3. Collection Deletion
4. Collection elements deletions,updates,insertions
5. Collection insertions
6. Entity Deletions

My problem is that #4 does not seam to work that way, it is doing them in reverse order. Its inserting updating and then deleting

[25/08/05 12:19:21:215 EST] 22652265 SystemOut O Hibernate: insert into Quotes.PROJECTDEFAULTFACTORIES (ID_FACTORY, ID_PROJECT, ID_Contact, ID_DEFAULTFACTORYMAP) values (?, ?, ?, default)
[25/08/05 12:19:21:231 EST] 22652265 SystemOut O Hibernate: values identity_val_local()
[25/08/05 12:19:21:247 EST] 22652265 SystemOut O Hibernate: update Quotes.PROJECTDEFAULTQUANTATIES set QUANTITY=?, DISABLED=?, SHOWTIMELINE=?, PROJECTID=?, TIMELINEID=? where QUANTITYID=?
[25/08/05 12:19:21:247 EST] 22652265 SystemOut O Hibernate: update Quotes.PROJECTDEFAULTQUANTATIES set QUANTITY=?, DISABLED=?, SHOWTIMELINE=?, PROJECTID=?, TIMELINEID=? where QUANTITYID=?
[25/08/05 12:19:21:247 EST] 22652265 SystemOut O Hibernate: delete from Quotes.PROJECTDEFAULTFACTORIES where ID_DEFAULTFACTORYMAP=?

Thanks
Dave


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 25, 2005 9:40 am 
Expert
Expert

Joined: Fri Aug 19, 2005 2:11 pm
Posts: 628
Location: Cincinnati
I'm guessing there are constraint violations because the new values that are being inserted are supposed to be unique or are part of the primary key??

If so, maybe try a surrogate key as your primary key.

Or is it a constraint violation in that something from another table needs to only point to one row in your collection?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 25, 2005 10:06 am 
Expert
Expert

Joined: Fri Aug 19, 2005 2:11 pm
Posts: 628
Location: Cincinnati
Quote:
remove the whole collection (in one SQL DELETE) and insert all five current elements (one by one)

Hibernate isn't smart enough to know that the second option is probably quicker in this case. (And it would probably be undesirable for Hibernate to be that smart; such behaviour might confuse database triggers, etc.)

Fortunately, you can force this behaviour (ie. the second strategy) at any time by discarding (ie. dereferencing) the original collection and returning a newly instantiated collection with all the current elements. This can be very useful and powerful from time to time.

http://www.hibernate.org/hib_docs/refer ... mance.html
Section 14.1.4

I think this might solve your problem.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 29, 2005 2:27 am 
Newbie

Joined: Wed Aug 24, 2005 1:08 am
Posts: 8
When I create a new Arraylist, populate with all the existing elements, and replace the old collection with this new array just before the update i get an exception:

Don't dereference a collection with cascade="all,delete-orphan"

I tried to change the mapping to cascade="all", it then as expected it does not delete any entries in the collection.

I tried reconnecting the session 1st, and then replacing the collection. But it appears that hibernate does not monitor for changes in objects once there session has been disconnect, even if the same session is reconnected. I have even tried creating a transaction, and commiting it after making the changes, but that still didnt catch the changes.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.