Announcement Announcement Module
Collapse
No announcement yet.
Unviolated @UniqueConstraint causes DataIntegrityViolationException Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Unviolated @UniqueConstraint causes DataIntegrityViolationException

    I have a Hibernate entity class in which I want to have two columns forming a unique constraint, i.e. the combination of the two fields must be a unique tuple. I have configured this constraint using the @Table and @UniqueConstraint annotations.

    Below is an example entity class:
    Code:
    @Entity(name = "MODULE_DEFINITION")
    @Table(name = "MODULE_DEFINITION", uniqueConstraints = { @UniqueConstraint(columnNames = { "NAME", "VERSION" }) })
    public class ModuleDefinition
        extends AbstractBaseEntity<Long>
    {
    
        private String name;
        private String version;
        private String description;
    
        @Column(name = "NAME", nullable = false)
        public String getName()
        {
            return this.name;
        }
    
        @Column(name = "VERSION", nullable = false)
        public String getVersion()
        {
            return this.version;
        }
    
        @Column(name = "DESCRIPTION", nullable = true)
        public String getDescription()
        {
            return description;
        }
    
        public void setDescription(final String description)
        {
            this.description = description;
        }
    
        public void setName(final String name)
        {
            this.name = name;
        }
    
        public void setVersion(final String version)
        {
            this.version = version;
        }
    
    }
    I am getting unexpected exceptions when I try to save a second record which does not violate the unique constraint -- the record is saved but then the Spring Framework seems to catch an exception from Hibernate and bubbles it up to my program which assumes it to be an error which it doesn't actually appear to be (at least the record is being saved successfully, but something else must not be right).

    For example I can save a record #1 into the table with name/version = web/0001 and then save the a record #2 into the table with name/version = web/0002 but I will then get an exception which looks like this:

    Code:
    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:636)
            at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:789)
            at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:663)
            at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:732)
            at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:701)
            at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:321)
            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.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
            at com.abc.network.lifecycle.cli.LifecycleManagerCli$$EnhancerByCGLIB$$5d507128.processCommandLine(<generated>)
            at com.abc.network.lifecycle.cli.LifecycleManagerCli.main(LifecycleManagerCli.java:197)
    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:266)
            at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:171)
            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:655)
            ... 10 more
    Caused by: java.sql.BatchUpdateException: Duplicate entry '2' for key 1
            at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1666)
            at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1082)
            at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
            at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
            ... 18 more
    Does any of this make sense to anyone? Can anyone suggest how I'd go about avoiding this exception?

    I am using the latest releases of Spring, Hibernate, and MySQL.

    Thanks in advance for any ideas, suggestions, etc.

    --James
Working...
X