Hi,
I am having an issue, where hibernate is determining that an updated entity needs to be inserted again, rather than update. This causes a constraint error on the database side because it's violating the unique key.
The relevant code section is as follows:
Code:
@Entity
@Table(name = "CachedPerson")
public class CachedPersonDTO {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long idPerson;
.
@Column(name = "firstName", length = 3, nullable = false)
private String firstName;
.
@ManyToOne (optional=false, cascade = { CascadeType.ALL }, fetch = FetchType.EAGER)
@OnDelete(action = OnDeleteAction.NO_ACTION)
@Fetch(value = FetchMode.SELECT)
@JoinColumn (name="firstName", referencedColumnName="requestedName", unique = false, nullable = false, insertable = false, updatable = false)
private CachedPersonConfig cachedPersonConfig;
.
.
.
}
@XmlRootElement
@Entity
@Table(name = "CachedPersonConfig")
public class CachedPersonConfig implements java.io.Serializable {
.
.
.
@XmlTransient
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "idCachedPersonConfig", unique = true, nullable = false)
private long idCachedPersonConfig;
@Column(name = "requestedName", length = 3)
private String requestedName;
.
.
.
}
When CachedPersonDTO is created to start with, CachedPersonConfig is null.
I can save the CachedPersonDTO fine, and an Id is set into the object.
When I try to setCachedPersonConfig(config); and then save it, hibernate then attempts to insert rather than update the original CachedPersonDTO.
The CachedPersonConfig will be shared between different CachedPersonDTO instances, and the config is the same based on the firstName, and requestedName. Anyone with the same firstName will share the same CachedPersonConfig.
I do not want to have multiple copies of CachedPersonConfig per CachedPersonDTO.
Please let me know how I can encourage Hibernate to update rather than insert.
The stack trace which happens is as follows:
Code:
Caused by: org.hibernate.exception.ConstraintViolationException: Duplicate entry 'John' for key 'uniquePersonIndex'
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:74) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at com.sun.proxy.$Proxy170.executeUpdate(Unknown Source) ~[na:na]
at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:96) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:58) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2870) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3381) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:203) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:183) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:167) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:320) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:287) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:126) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.ejb.event.EJB3MergeEventListener.saveWithGeneratedId(EJB3MergeEventListener.java:71) ~[hibernate-entitymanager-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.saveTransientEntity(DefaultMergeEventListener.java:236) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:216) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:282) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:76) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:904) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:888) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:892) ~[hibernate-core-4.1.6.Final.jar:4.1.6.Final]
at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:879) ~[hibernate-entitymanager-4.1.6.Final.jar:4.1.6.Final]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_25]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_25]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_25]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_25]
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240) ~[spring-orm-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at com.sun.proxy.$Proxy51.merge(Unknown Source) ~[na:na]
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:345) ~[spring-data-jpa-1.2.0.RELEASE.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_25]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_25]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_25]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_25]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:334) ~[spring-data-commons-core-1.4.0.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:319) ~[spring-data-commons-core-1.4.0.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96) ~[spring-tx-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260) ~[spring-tx-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94) ~[spring-tx-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.2.2.RELEASE.jar:3.2.2.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155) ~[spring-tx-3.2.2.RELEASE.jar:3.2.2.RELEASE]
... 25 common frames omitted
Thanks in advance!