当我尝试调用saveorupdate()方法时,在休眠中发生重复输入

时间:2013-07-18 08:23:53

标签: java spring hibernate

我的应用程序包含几个并发运行的线程,所有线程都在我的表中插入或更新了几行,所以我使用saveOrUpdate()来避免重复输入问题。但它发生了好几次。

我的表结构

CREATE TABLE `question` (`id` varchar(100) CHARACTER SET latin1 NOT NULL COMMENT 'It will be the post_id in )

我的HBM

<class name="com.xminds.bestfriend.frontend.model.Question" table="question" >
    <id name="id" type="string">
        <column name="id" length="100" />
        <generator class="assigned" />
    </id>
    <many-to-one name="users" class="com.xminds.bestfriend.frontend.model.Users" fetch="select">
        <column name="answer_uid" />
    </many-to-one>
    <many-to-one name="questionType" class="com.xminds.bestfriend.frontend.model.QuestionType" fetch="select">

        <column name="question_type_id" />
    </many-to-one>
    <property name="data1" type="string">
        <column name="data1" length="65535" />
    </property>
    <property name="data2" type="string">
        <column name="data2" length="65535" />
    </property>
    <property name="fbCreatedDate" type="timestamp">
        <column name="fb_created_date" length="19" />
    </property>
    <property name="permaLink" type="string">
        <column name="perma_link" length="1000" />
    </property>
    <property name="fbUpdatedDate" type="timestamp">
        <column name="fb_updated_date" length="19" />
    </property>
    <property name="contentActivity" type="java.lang.Integer">
        <column name="content_activity" />
    </property>
    <property name="nbConsumptions" type="int">
        <column name="nb_consumptions" not-null="true" />
    </property>
    <property name="createdDate" type="date">
        <column name="created_date" length="10" />
    </property>
    <property name="updatedDate" type="date">
        <column name="updated_date" length="10" />
    </property>
    <property name="cover_url" type="string">
      <column name="cover_url" length="1000"/>
    </property>

    <property name="category" type="string">
      <column name="category" length="1000"/>
    </property>
    <property name="width" type="int">
        <column name="width" not-null="true" />
    </property>
    <property name="height" type="int">
        <column name="height" not-null="true" />
    </property>
    <property name="coverOffsetX" type="java.lang.Integer">
        <column name="cover_offset_x" />
    </property>
    <property name="coverOffsetY" type="java.lang.Integer">
        <column name="cover_offset_y" />
    </property>
    <property name="latitude" type="java.lang.Double">
        <column name="latitude" precision="12" scale="0" />
    </property>
    <property name="longitude" type="java.lang.Double">
        <column name="longitude" precision="12" scale="0" />
    </property>
    <property name="is_active" type="boolean">
        <column name="is_active" not-null="true" />
    </property>
    <set name="questionConsumptions" inverse="true">
        <key>
            <column name="question_id" length="100" not-null="true">
                <comment>QuestionId</comment>
            </column>
        </key>
        <one-to-many class="com.xminds.bestfriend.frontend.model.QuestionConsumption" />
    </set>
</class>

获得异常

WARN  JDBCExceptionReporter - SQL Error: 1062, SQLState: 23000

错误JDBCExceptionReporter - 重复条目&#39; 1019306207_10200395396740374&#39;关键&#39; PRIMARY&#39; 错误AbstractFlushingEventListener - 无法将数据库状态与会话同步 org.hibernate.exception.ConstraintViolationException:无法插入:[com.xminds.bestfriend.frontend.model.Question]     在org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)     在org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)     在org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2436)     在org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2856)     在org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)     在org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)     在org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265)     在org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)     在org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)     在org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)     在org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)     在org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)     在org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)     在org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)     在org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)     在org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)     在org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:147)     在com.xminds.bestfriend.consumers.Base.onMessage(Base.java:89)     在org.springframework.jms.listener.adapter.MessageListenerAdapter.onMessage(MessageListenerAdapter.java:339)     在org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:535)     在org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:495)     在org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:467)     在org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325)     在org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263)     at org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1058)     at org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1050)     在org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:947)     在java.lang.Thread.run(Thread.java:679) 引起:com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:重复条目&#39; 1019306207_10200395396740374&#39;关键&#39; PRIMARY&#39;     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)     at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)     at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)     at java.lang.reflect.Constructor.newInstance(Constructor.java:532)     在com.mysql.jdbc.Util.handleNewInstance(Util.java:411)     在com.mysql.jdbc.Util.getInstance(Util.java:386)     在com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1039)     在com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3597)     在com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3529)     在com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1990)     在com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2151)     在com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2625)     在com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2119)     在com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2415)     在com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2333)     在com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2318)     at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)     在org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:46)     在org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2416)     ......还有25个 错误QuestionGeneration - 无法处理任务ID:208 org.springframework.dao.DataIntegrityViolationException:无法插入:[com.xminds.bestfriend.frontend.model.Question]; SQL [插入问题(answer_uid,question_type_id,data1,data2,fb_created_date,perma_link,fb_updated_date,content_activity,nb_consumptions,created_date,updated_date,cover_url,category,width,height,cover_offset_x,cover_offset_y,latitude,longitude,is_active,id)值( ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)];约束[null];嵌套异常是org.hibernate.exception.ConstraintViolationException:无法插入:[com.xminds.bestfriend.frontend.model.Question]     在org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:637)     在org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:793)     在org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:664)     在org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)     在org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)     在org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:147)     在com.xminds.bestfriend.consumers.Base.onMessage(Base.java:89)     在org.springframework.jms.listener.adapter.MessageListenerAdapter.onMessage(MessageListenerAdapter.java:339)     在org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:535)     在org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:495)     在org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:467)     在org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325)     在org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263)     at org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1058)     at org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1050)     在org.springframework.jms.listener.DefaultMessageListenerContainer $ AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:947)     在java.lang.Thread.run(Thread.java:679) 引起:org.hibernate.exception.ConstraintViolationException:无法插入:[com.xminds.bestfriend.frontend.model.Question]     在org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)     在org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)     在org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2436)     在org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2856)     在org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)     在org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)     在org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265)     在org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)     在org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)     在org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)     在org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)     在org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)     在org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)     在org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)     ......还有14个 引起:com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:重复条目&#39; 1019306207_10200395396740374&#39;关键&#39; PRIMARY&#39;     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)     at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)     at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)     at java.lang.reflect.Constructor.newInstance(Constructor.java:532)     在com.mysql.jdbc.Util.handleNewInstance(Util.java:411)     在com.mysql.jdbc.Util.getInstance(Util.java:386)     在com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1039)     在com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3597)     在com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3529)     在com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1990)     在com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2151)     在com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2625)     在com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2119)     在com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2415)     在com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2333)     在com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2318)     at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)     在org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:46)     在org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2416)     ......还有25个

@Override
public void saveOrUpdate(Object instance)
{

    //log.debug("attaching dirty  instance");
    try
    {
        getHibernateTemplate().saveOrUpdate(instance);
        //log.debug("attach successful");
    }
    catch (RuntimeException re)
    {
       // log.error("attach failed", re);
        throw re;
    }

}

2 个答案:

答案 0 :(得分:0)

你说,“我的应用程序包含几个并发运行的线程,所有线程都在我的表中插入或更新了几行”。并且您手动设置您的ID。 我想知道,你为你的线程设置的ID,你是如何得到它们的?

答案 1 :(得分:0)

你说&#39;在我的情况下,id(主键)不会自动递增,每次我都会设置它的值&#39;。这就是问题。在多个线程中,您应该确保自己生成的id应该是唯一的。

有两种方式,1,使用自动增量列 2,使用像UUID这样的东西来创建id。如果你只使用一个带有多个线程的jvm,有很多方法或库可以帮助你做到这一点。