Problem description:
My classes that use a Long key that are generated from an oracle sequence work just fine. I can execute saveOrUpdate and it will know when to do an update or an insert. For some of my small classes that are only String Code/String Description, where the code is the @Id, Hibernate seems to be unable to determine that a class has already been saved and creates an insert statement twice.
It is saving correctly, as I can execute my find method to retrieve the saved class. One of the main things I noticed is that the Hibernate queries don't seem to be able to handle putting quotes around my Id (e.g. WHERE code = 'CODE'). Any pointers would be greatly appreciated.
Hibernate version: 3
Mapping documents:
Code:
@Entity
@Table(name="BTD_COUNT_TYPE",catalog="BTD")
public class CountType implements Serializable {
private String code;
private String description;
public CountType() { }
public CountType(String code) {
this.code = code;
}
@Id
@Column(name="COUNT_TYPE_CODE", unique=true, nullable=false, length=20)
public String getCode() {
return this.code;
}
public void setCode(String code) {
this.code = code;
}
@Column(name="COUNT_TYPE_DESCRIPTION")
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
}
Code between sessionFactory.openSession() and session.close():Code:
CountType countType = new CountType("COUNT");
service.save(countType);
countType.setDescription("COUNT DESC");
service.save(countType);
Code:
public void save(CountType countType) {
logger.info("save CountType: " + countType);
getHibernateTemplate().saveOrUpdate(countType);
}
Full stack trace of any exception that occurs:Code:
Exception in thread "main" org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:622)
at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:690)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:566)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:662)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:632)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:319)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy27.save(Unknown Source)
at com.cisco.btd.playground.jared2.TestClass.main(TestClass.java:53)
Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
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.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:558)
... 10 more
Caused by: java.sql.BatchUpdateException: ORA-00001: unique constraint (BTD.COUNT_TYPE_PK) violated
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10768)
at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
... 18 more
Name and version of the database you are using: Oracle 10g
The generated SQL (show_sql=true):Code:
Hibernate:
select
counttype_.COUNT_TYPE_CODE,
counttype_.COUNT_TYPE_DESCRIPTION as COUNT2_30_
from
BTD.BTD_COUNT_TYPE counttype_
where
counttype_.COUNT_TYPE_CODE=?
Hibernate:
insert
into
BTD.BTD_COUNT_TYPE
(COUNT_TYPE_DESCRIPTION, COUNT_TYPE_CODE)
values
(?, ?)
2008-12-24 11:17:58,845 com.cisco.btd.service.WeeklyRollupServiceImpl [INFO] - save CountType: com.cisco.btd.model.CountType@13c33b7
Hibernate:
select
counttype_.COUNT_TYPE_CODE,
counttype_.COUNT_TYPE_DESCRIPTION as COUNT2_30_
from
BTD.BTD_COUNT_TYPE counttype_
where
counttype_.COUNT_TYPE_CODE=?
Hibernate:
insert
into
BTD.BTD_COUNT_TYPE
(COUNT_TYPE_DESCRIPTION, COUNT_TYPE_CODE)
values
(?, ?)
[/code]