-->
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.  [ 4 posts ] 
Author Message
 Post subject: [Hibernate/JPA] Detached entities not properly recognised
PostPosted: Tue Sep 11, 2007 4:23 am 
Newbie

Joined: Thu Apr 27, 2006 4:56 am
Posts: 12
I have 2 entities, that uses a manually assigned string ID, using UUID like this:

Code:
@Id
@Column(length=36)
protected String id = UUID.randomUUID().toString();


The 2 entities:

User (which represents a user, with no relation to other entities)
Collection (which represents a collection and has a @ManyToOne relation with user).

If I persist, merge, find, etc... user alone, everything works perfectly. The same with collection.

But when I try to MERGE a user (in order to update some of its basic fields, like name, etc...) and there is a collection that references the user with a foreign key, I get an exception like this:

Code:
Exception in thread "main" org.springframework.dao.DataIntegrityViolationException: org.hibernate.exception.ConstraintViolationException: could not delete: [kollector.dom.User#55fa5a30-ea48-412d-a56e-85ebce52d047]; nested exception is javax.persistence.EntityExistsException: org.hibernate.exception.ConstraintViolationException: could not delete: [kollector.dom.User#55fa5a30-ea48-412d-a56e-85ebce52d047]
   at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:246)
   at org.springframework.orm.jpa.DefaultJpaDialect.translateExceptionIfPossible(DefaultJpaDialect.java:113)
   at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:212)
   at org.springframework.orm.jpa.JpaAccessor.translateIfNecessary(JpaAccessor.java:152)
   at org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:196)
   at org.springframework.orm.jpa.JpaTemplate.merge(JpaTemplate.java:270)
   at kollector.dao.AbstractJpaDao.update(AbstractJpaDao.java:57)
   at kollector.service.AbstractDaoManager.update(AbstractDaoManager.java:73)
   at kollector.service.AbstractDaoManager.update(AbstractDaoManager.java:1)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:293)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:177)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
   at $Proxy79.update(Unknown Source)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:293)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:177)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
   at $Proxy80.update(Unknown Source)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:293)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:177)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
   at org.springframework.remoting.support.RemoteInvocationTraceInterceptor.invoke(RemoteInvocationTraceInterceptor.java:70)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
   at $Proxy81.update(Unknown Source)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at org.springframework.remoting.support.RemoteInvocation.invoke(RemoteInvocation.java:205)
   at org.acegisecurity.context.rmi.ContextPropagatingRemoteInvocation.invoke(ContextPropagatingRemoteInvocation.java:103)
   at org.springframework.remoting.support.DefaultRemoteInvocationExecutor.invoke(DefaultRemoteInvocationExecutor.java:38)
   at org.springframework.remoting.support.RemoteInvocationBasedExporter.invoke(RemoteInvocationBasedExporter.java:76)
   at org.springframework.remoting.rmi.RmiBasedExporter.invoke(RmiBasedExporter.java:72)
   at org.springframework.remoting.rmi.RmiInvocationWrapper.invoke(RmiInvocationWrapper.java:72)
   at sun.reflect.GeneratedMethodAccessor11.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:294)
   at sun.rmi.transport.Transport$1.run(Transport.java:153)
   at java.security.AccessController.doPrivileged(Native Method)
   at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
   at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:466)
   at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:707)
   at java.lang.Thread.run(Thread.java:613)
   at org.springframework.remoting.support.RemoteInvocationUtils.fillInClientStackTraceIfPossible(RemoteInvocationUtils.java:47)
   at org.springframework.remoting.rmi.RmiClientInterceptor.doInvoke(RmiClientInterceptor.java:345)
   at org.springframework.remoting.rmi.RmiClientInterceptor.invoke(RmiClientInterceptor.java:257)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
   at $Proxy26.update(Unknown Source)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:589)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:293)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:177)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
   at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:126)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
   at $Proxy27.update(Unknown Source)
   at aristotele.MakeDB.main(MakeDB.java:126)
Caused by: javax.persistence.EntityExistsException: org.hibernate.exception.ConstraintViolationException: could not delete: [kollector.dom.User#55fa5a30-ea48-412d-a56e-85ebce52d047]
   at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:605)
   at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:237)
   at org.springframework.orm.jpa.JpaTemplate$6.doInJpa(JpaTemplate.java:272)
   at org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:191)
   ... 75 more
Caused by: org.hibernate.exception.ConstraintViolationException: could not delete: [kollector.dom.User#55fa5a30-ea48-412d-a56e-85ebce52d047]
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2541)
   at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2697)
   at org.hibernate.action.EntityDeleteAction.execute(EntityDeleteAction.java:74)
   at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:146)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
   at org.hibernate.impl.SessionImpl.forceFlush(SessionImpl.java:1021)
   at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:165)
   at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
   at org.hibernate.ejb.event.EJB3MergeEventListener.saveWithGeneratedId(EJB3MergeEventListener.java:43)
   at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:186)
   at org.hibernate.event.def.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:240)
   at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:120)
   at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53)
   at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677)
   at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661)
   at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665)
   at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:228)
   ... 77 more
Caused by: org.postgresql.util.PSQLException: ERROR: update or delete on table "users" violates foreign key constraint "fkf078abe3e45005f" on table "collection"
  Detail: Key (id)=(55fa5a30-ea48-412d-a56e-85ebce52d047) is still referenced from table "collection".
   at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1548)
   at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1316)
   at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:191)
   at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452)
   at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:351)
   at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:305)
   at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)
   at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2523)
   ... 97 more


Strange thing is that I'm merging an already persisted unit, the unit I'm passing to the merge have EXACTLY THE SAME ID as the one already persisted in the database, so I would think hibernate would have just to do an UPDATE of that row, instead of first calling for a DELETE, which breaks up because of the foreign key constraint on collection towards this user.

Pseudo code would be something like:

Code:
Persist New USER (OK)
Find again USER for reloading it (OK)
(Modify some basic fields of USER)
Merge USER (OK, this works here)

Persist New COLLECTION with this USER reference inside (OK)
Find again USER for reloading it (OK)
(Modify some basic fields of USER)
Merge USER (EXCEPTION - this is calling the delete)



Notice the:

Code:
Caused by: org.hibernate.exception.ConstraintViolationException: could not delete: [kollector.dom.User#55fa5a30-ea48-412d-a56e-85ebce52d047]
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2541)
   at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2697)
   at org.hibernate.action.EntityDeleteAction.execute(EntityDeleteAction.java:74)
   at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:146)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
   at org.hibernate.impl.SessionImpl.forceFlush(SessionImpl.java:1021)
   at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:165)
   at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
   at org.hibernate.ejb.event.EJB3MergeEventListener.saveWithGeneratedId(EJB3MergeEventListener.java:43)
   at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:186)
   at org.hibernate.event.def.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:240)
   at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:120)
   at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53)
   at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677)
   at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661)
   at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665)


Hibernate calls for a merge, which calls a 'save', which then calls for a DELETE on flush. (????)

Why is this happening? Why is hibernate triggering a DELETE, when I'm just handing over an already persisted entity with the proper ID for update?

Shouldn't the merge recognise the identity is already persisted by the ID and trigger an update instead of this DELETE I cannot possibly explain?

Probably it's because something is leading hibernate to think this is a transient entity to persist again or something like that, and this happens because of this.

But why? The entity i'm handing to the merge method is just newly refreshed (find) from the context and has the correct ID inside of the persistent entity available in the DB, I've checked it twice already.

Shoudn't be the ID the 'unsaved value' that hibernate uses to recognise if an entity is detached or transient?

I'm really lost here, dunno what's wrong or how I can fix this, please help me out... ;-)


Last edited by omero on Tue Sep 11, 2007 6:46 am, edited 2 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 11, 2007 6:38 am 
Newbie

Joined: Thu Apr 27, 2006 4:56 am
Posts: 12
I've done some more research on this problem.

I tried switching the ID from manually assigned to DB-generated (@GeneratedValue(strategy=GenerationType.IDENTITY)) and redid the test.

The same thing happen: instead of properly recognizing the entity as DETACHED (the ID in the instance is the same as the one on the database) and performing the update, hibernate assumes this is a new instance and try an insert, which fails of course because of some unique constaints (username in user is unique).

Code:
org.springframework.dao.DataIntegrityViolationException: org.hibernate.exception.ConstraintViolationException: could not insert: [kollector.dom.User]; nested exception is javax.persistence.EntityExistsException: org.hibernate.exception.ConstraintViolationException: could not insert: [kollector.dom.User]
   at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:246)
   at org.springframework.orm.jpa.DefaultJpaDialect.translateExceptionIfPossible(DefaultJpaDialect.java:113)
   at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:212)
   at org.springframework.orm.jpa.JpaAccessor.translateIfNecessary(JpaAccessor.java:152)
   at org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:196)
   at org.springframework.orm.jpa.JpaTemplate.merge(JpaTemplate.java:270)
   at kollector.dao.AbstractJpaDao.update(AbstractJpaDao.java:57)
   at kollector.service.AbstractDaoManager.update(AbstractDaoManager.java:73)
   at kollector.service.AbstractDaoManager.update(AbstractDaoManager.java:1)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:293)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:177)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
   at $Proxy80.update(Unknown Source)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:293)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:177)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
   at $Proxy81.update(Unknown Source)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:293)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:177)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
   at org.springframework.remoting.support.RemoteInvocationTraceInterceptor.invoke(RemoteInvocationTraceInterceptor.java:70)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
   at $Proxy82.update(Unknown Source)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at org.springframework.remoting.support.RemoteInvocation.invoke(RemoteInvocation.java:205)
   at org.acegisecurity.context.rmi.ContextPropagatingRemoteInvocation.invoke(ContextPropagatingRemoteInvocation.java:103)
   at org.springframework.remoting.support.DefaultRemoteInvocationExecutor.invoke(DefaultRemoteInvocationExecutor.java:38)
   at org.springframework.remoting.support.RemoteInvocationBasedExporter.invoke(RemoteInvocationBasedExporter.java:76)
   at org.springframework.remoting.rmi.RmiBasedExporter.invoke(RmiBasedExporter.java:72)
   at org.springframework.remoting.rmi.RmiInvocationWrapper.invoke(RmiInvocationWrapper.java:72)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:294)
   at sun.rmi.transport.Transport$1.run(Transport.java:153)
   at java.security.AccessController.doPrivileged(Native Method)
   at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
   at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:466)
   at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:707)
   at java.lang.Thread.run(Thread.java:613)
Caused by: javax.persistence.EntityExistsException: org.hibernate.exception.ConstraintViolationException: could not insert: [kollector.dom.User]
   at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:605)
   at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:237)
   at org.springframework.orm.jpa.JpaTemplate$6.doInJpa(JpaTemplate.java:272)
   at org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:191)
   ... 58 more
Caused by: org.hibernate.exception.ConstraintViolationException: could not insert: [kollector.dom.User]
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:40)
   at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2158)
   at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2638)
   at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:48)
   at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
   at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:298)
   at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
   at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:107)
   at org.hibernate.ejb.event.EJB3MergeEventListener.saveWithGeneratedId(EJB3MergeEventListener.java:43)
   at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:186)
   at org.hibernate.event.def.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:240)
   at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:120)
   at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53)
   at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677)
   at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661)
   at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665)
   at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:228)
   ... 60 more
Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key violates unique constraint "users_username_key"
   at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1548)
   at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1316)
   at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:191)
   at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452)
   at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:351)
   at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:305)
   at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)
   at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:33)
   ... 76 more



You can see the problem is the same here: org.hibernate.event.def.DefaultMergeEventListener.onMerge checks the state and see it's detached, but then in the org.hibernate.event.def.DefaultMergeEventListener.entityIsDetached something goes wrong and hibernate assumes its transient.

This is the source snippet of this method:

Code:
   protected void entityIsDetached(MergeEvent event, Map copyCache) {
      
      log.trace("merging detached instance");
      
      final Object entity = event.getEntity();
      final EventSource source = event.getSession();

      final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
      final String entityName = persister.getEntityName();
         
      Serializable id = event.getRequestedId();
      if ( id == null ) {
         id = persister.getIdentifier( entity, source.getEntityMode() );
      }
      else {
         // check that entity id = requestedId
         Serializable entityId = persister.getIdentifier( entity, source.getEntityMode() );
         if ( !persister.getIdentifierType().isEqual( id, entityId, source.getEntityMode(), source.getFactory() ) ) {
            throw new HibernateException( "merge requested with id not matching id of passed entity" );
         }
      }
      
      String previousFetchProfile = source.getFetchProfile();
      source.setFetchProfile("merge");
      //we must clone embedded composite identifiers, or
      //we will get back the same instance that we pass in
      final Serializable clonedIdentifier = (Serializable) persister.getIdentifierType()
            .deepCopy( id, source.getEntityMode(), source.getFactory() );
      final Object result = source.get(entityName, clonedIdentifier);
      source.setFetchProfile(previousFetchProfile);
      
      if ( result == null ) {
         //TODO: we should throw an exception if we really *know* for sure 
         //      that this is a detached instance, rather than just assuming
         //throw new StaleObjectStateException(entityName, id);
         
         // we got here because we assumed that an instance
         // with an assigned id was detached, when it was
         // really persistent
         entityIsTransient(event, copyCache);
      }
      else {
         copyCache.put(entity, result); //before cascade!
   
         final Object target = source.getPersistenceContext().unproxy(result);
         if ( target == entity ) {
            throw new AssertionFailure("entity was not detached");
         }
         else if ( !source.getEntityName(target).equals(entityName) ) {
            throw new WrongClassException(
                  "class of the given object did not match class of persistent copy",
                  event.getRequestedId(),
                  entityName
               );
         }
         else if ( isVersionChanged( entity, source, persister, target ) ) {
            if ( source.getFactory().getStatistics().isStatisticsEnabled() ) {
               source.getFactory().getStatisticsImplementor()
                     .optimisticFailure( entityName );
            }
            throw new StaleObjectStateException( entityName, event.getRequestedId() );
         }
   
         // cascade first, so that all unsaved objects get their
         // copy created before we actually copy
         cascadeOnMerge(source, persister, entity, copyCache);
         copyValues(persister, entity, target, source, copyCache);
         
         //copyValues works by reflection, so explicitly mark the entity instance dirty
         markInterceptorDirty( entity, target );
         
         event.setResult(result);
      }

   }


You can see that for some reason result is null and therefore hibernate wrongly assumes this is a transient entity.

Also notices the javadoc in the code when this happens, there used to be an exception here:

Code:
      if ( result == null ) {
         //TODO: we should throw an exception if we really *know* for sure 
         //      that this is a detached instance, rather than just assuming
         //throw new StaleObjectStateException(entityName, id);
         
         // we got here because we assumed that an instance
         // with an assigned id was detached, when it was
         // really persistent
         entityIsTransient(event, copyCache);


Why this can happen? Why hibernate doesn't seem to be able to properly recognise my detached instances? They have the ID correctly valued in the java object, I checked it 10000000000000 times already :)

Anyone can help?


Top
 Profile  
 
 Post subject: Found problem
PostPosted: Tue Sep 11, 2007 9:29 am 
Newbie

Joined: Thu Apr 27, 2006 4:56 am
Posts: 12
I think I've found the problem, thanks to everyone who helped :)


Top
 Profile  
 
 Post subject: Solution?
PostPosted: Sun Jan 13, 2008 4:42 pm 
Newbie

Joined: Sat Jun 17, 2006 12:30 am
Posts: 3
Would have been helpful to other folks who have similar problems if you had posted what your solution was.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 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.