【问题标题】:Duplicate entry '1' for key 'UK_tbce3olw19taxx6srova86xok'密钥“UK_tbce3olw19taxx6srova86xok”的重复条目“1”
【发布时间】:2013-10-07 11:16:37
【问题描述】:

大家好。

我正在尝试弄清楚如何处理 Hibernate。在我的测试中,我使用 Hibernate 继承,这是我遇到的异常:

Hibernate: select theuser0_.ID as ID1_2_0_, theuser0_.FIRST_NAME as FIRST_NA3_2_0_, theuser0_.LAST_NAME as LAST_NAM4_2_0_, theuser0_.PASSWORD as PASSWORD5_2_0_, theuser0_.EMALE as EMALE6_2_0_, theuser0_.GENDER as GENDER7_2_0_, theuser0_.UCI_PERSON_ADDRESS as UCI_PERS8_2_0_, theuser0_.UCI_PERSON_PHONE as UCI_PERS9_2_0_, theuser0_.USER_INFO_TYPE as USER_INF2_2_0_ from USER theuser0_ where theuser0_.ID=?
Hibernate: insert into USER_EVENTS (EVENT_DATE, USER_ID, EVENT_INDEX) values (?, ?, ?)
Oct 07, 2013 2:51:53 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 1062, SQLState: 23000
Oct 07, 2013 2:51:53 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Duplicate entry '1' for key 'UK_tbce3olw19taxx6srova86xok'
Exception in thread "main" org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:138)
    at org.springframework.orm.hibernate4.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:680)
    at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:562)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:755)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:724)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:475)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:270)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at com.sun.proxy.$Proxy7.saveUser(Unknown Source)
    at demidov.pkg.persistence.AppOut.main(AppOut.java:36)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:74)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:136)
    at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:96)
    at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:58)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2975)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3487)
    at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:377)
    at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:214)
    at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:194)
    at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:178)
    at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:321)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:286)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:192)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:206)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:191)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:114)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
    at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:735)
    at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:727)
    at org.hibernate.engine.spi.CascadingAction$5.cascade(CascadingAction.java:258)
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:388)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:331)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:209)
    at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:418)
    at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:358)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:334)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:209)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:166)
    at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:162)
    at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:153)
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:89)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1234)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
    at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:554)
    ... 9 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'UK_tbce3olw19taxx6srova86xok'
    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:526)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.Util.getInstance(Util.java:386)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4190)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4122)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2818)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2157)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2460)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2377)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2361)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133)
    ... 46 more

我确实有两个父实体:第一个是带有子类 UserInfo 的 TheUser:

public class TheUser {


    private int userId;

        public int getUserId() {
            return userId;
        }

        public void setUserId(int userId) {
            this.userId = userId;
        }



    private String userFirstName;

        public String getUserFirstName() {
            return userFirstName;
        }

        public void setUserFirstName(String userFirstName) {
            this.userFirstName = userFirstName;
        }



    private String userLastName;

        public String getUserLastName() {
            return userLastName;
        }

        public void setUserLastName(String userLastName) {
            this.userLastName = userLastName;
        }



    private String userPassword;

        public String getUserPassword() {
            return userPassword;
        }

        public void setUserPassword(String userPassword) {
            this.userPassword = userPassword;
        }



    private String userEmale;

        public String getUserEmale() {
            return userEmale;
        }

        public void setUserEmale(String userEmale) {
            this.userEmale = userEmale;
        }



    private String userGender;

        public String getUserGender() {
            return userGender;
        }

        public void setUserGender(String userGender) {
            this.userGender = userGender;
        }



    private List<UserEvents> userEventsList = new ArrayList<UserEvents>();

        public List<UserEvents> getUserEventsList() {
            return userEventsList;
        }

        public void setUserEventsList(List<UserEvents> userEventsList) {
            this.userEventsList = userEventsList;
        }

这是 TheUser 的 xml 映射:

<class name="demidov.pkg.domain.TheUser" table="USER">

    <id name="userId" column="ID">
        <generator class="native"/>
    </id>


    <discriminator  column="USER_INFO_TYPE" type="string"/>


    <property name="userFirstName" column="FIRST_NAME" type="string"/>
    <property name="userLastName" column="LAST_NAME" type="string"/>
    <property name="userPassword" column="PASSWORD" type="string"/>
    <property name="userEmale" column="EMALE" type="string"/>
    <property name="userGender" column="GENDER" type="string"/>


    <list name="userEventsList" inverse="false" lazy="true" fetch="select" cascade="all" >

        <key column="USER_ID" not-null="true" />

        <index column="EVENT_INDEX" />          

        <one-to-many class="demidov.pkg.domain.UserEvents"/>        

    </list>


    <subclass name="demidov.pkg.domain.UserContactInfo" discriminator-value="UCI" >

        <property name="personAddress" column="UCI_PERSON_ADDRESS" />
        <property name="personPhoneNumber" column="UCI_PERSON_PHONE" />

    </subclass>


</class>

以及带有子类的 UserEvents:ComputerMaintenanceEvent 和 SoftwareDevelopmentEvent 实体:

public class UserEvents {



    private int userEventId;

        public int getUserEventId() {
            return userEventId;
        }

        public void setUserEventId(int userEventId) {
            this.userEventId = userEventId;
        }



    private Date userEventDate;     

        public Date getUserEventDate() {
            return userEventDate;
        }

        public void setUserEventDate(Date userEventDate) {
            this.userEventDate = userEventDate;
        }



    protected TheUser theUser;

        public TheUser getTheUser() {
            return theUser;
        }

        public void setTheUser(TheUser theUser) {
            this.theUser = theUser;
        }

}

用xml映射userevent:

<hibernate-mapping>


            <class name="demidov.pkg.domain.UserEvents" table="USER_EVENTS">


                <id name="userEventId" column="ID" type="integer">
                    <generator class="native"/>
                </id>


                <property name="userEventDate" column="EVENT_DATE" type="date"/>


                <many-to-one name="theUser" class="demidov.pkg.domain.TheUser" insert="false" update="false" lazy="false" fetch="select" cascade="save-update">
                    <column name="USER_ID" not-null="true" unique="true" />
                </many-to-one>


                <joined-subclass name="demidov.pkg.domain.ComputerMaintenanceEvent" table="MAINTENANCE_EVENT">

                    <key column="MAINTENANCE_ID" not-null="true"/>

                    <property name="descriptionMaintenance" column="DESCRIPTION_MAINTENANCE" type="string"/>
                    <property name="additionalInfoMaintenance" column="ADDITIONAL_INFO_MAINTENANCE" type="string"/>

                </joined-subclass>              


                <joined-subclass name="demidov.pkg.domain.SoftwareDevelopmentEvent" table="DEVELOPMENT_EVENT">

                    <key column="DEVELOPMENT_ID" not-null="true"/>

                    <property name="descriptionDevelopment" column="DESCRIPTION_DEVELOPMENT" type="string"/>
                    <property name="additionalInfoDevelopment" column="ADDITIONAL_INFO_DEVELOPMENT" type="string"/>

                </joined-subclass>


            </class>


        </hibernate-mapping>

在数据库中我已经插入了一次数据:

TheUser 实体 + subclass= 每个层次结构的继承表:

+----+----------------------------+------------+-----------+----------+-----------------+--------+--------------------+------------------+
| ID | USER_INFO_TYPE             | FIRST_NAME | LAST_NAME | PASSWORD | EMALE           | GENDER | UCI_PERSON_ADDRESS | UCI_PERSON_PHONE |
+----+----------------------------+------------+-----------+----------+-----------------+--------+--------------------+------------------+
|  1 | demidov.pkg.domain.TheUser | Vadim      | Demidov   | 123123   | vadim@google.ru | Male   | NULL               | NULL             |
+----+----------------------------+------------+-----------+----------+-----------------+--------+--------------------+------------------+

在 UserEvent 和子类之间:SoftwareDevelopmentEvent 和 ComputerMaitnanceEvent 是每个子类继承的表。

数据库中的 UserEvents 表:

+----+------------+---------+-------------+
| ID | EVENT_DATE | USER_ID | EVENT_INDEX |
+----+------------+---------+-------------+
|  1 | 2013-10-07 |       1 |           0 |
+----+------------+---------+-------------+

UserEvents 的子类 - SoftwareDevelopmentEvent:

+----------------+-------------------------+-----------------------------+
| DEVELOPMENT_ID | DESCRIPTION_DEVELOPMENT | ADDITIONAL_INFO_DEVELOPMENT |
+----------------+-------------------------+-----------------------------+
|              1 | Create website          | Create news portal          |
+----------------+-------------------------+-----------------------------+

我正在尝试向现有用户添加新事件:

public void saveUser(Integer id, List<UserEvents> listEvents) {

        Session session = sessionFactory.getCurrentSession();

        TheUser theuser = (TheUser)session.get(TheUser.class, id);

        theuser.setUserEventsList(listEvents);

        session.saveOrUpdate(theuser);

    }

主要方法:

List<UserEvents> eventsList = new ArrayList<UserEvents>();


        ComputerMaintenanceEvent sde = new ComputerMaintenanceEvent();
        sde.setDescriptionMaintenance("Fix PC");
        sde.setAdditionalInfoMaintenance("Fix my PC please");
        sde.setUserEventDate(new Date());
        eventsList.add(sde);


        dao.saveUser(1, eventsList);

请帮忙。 向您致以最诚挚的谢意。

^已解决的问题:问题出在我的 userevent.hbm.xml 中,我无意中将 unique="true" 设置为关系。

谢谢大家。

【问题讨论】:

    标签: mysql hibernate persistence hibernate-mapping


    【解决方案1】:

    您正在使用本机生成器类。

    <generator class="native"/>
    

    当您使用原生生成器时,您需要在数据库中创建一个序列。创建名为 HIBERNATE_SEQUENCE 的任何序列,然后尝试运行代码。

    也是因为下面的代码

    dao.saveUser(1, eventsList);
    

    每次执行程序时,程序都会尝试保存 id 为 1 的用户,但 id 为 1 的用户已经存在并且约束失败并且您得到异常。如果您希望自己处理,则需要保持 id 的唯一性。否则不要提供 id 并让 hibernate 使用底层序列为您生成它

    【讨论】:

    • 是的。我从这本书中得到它 本地身份生成器根据底层数据库的功能选择其他本地 AUTO 身份生成器,例如身份、序列或 hilo。使用此生成器可将您的映射元数据移植到不同的数据库管理系统。
    • HIBERNATE_SEQUENCE 存在吗?因为如果我添加它,我得到:在类路径资源 [spring-context.xml] 中定义名称为“sessionFactory”的 bean 创建错误:init 方法的调用失败;嵌套异常是 org.hibernate.MappingException:无法实例化 id 生成器 [entity-name=demidov.pkg.domain.TheUser]
    • 您可以在映射中提供序列名称,也可以在 mysql DB 中创建名称为“HIBERNATE_SEQUENCE”的序列。 Hibernate 会选择这个默认序列并生成 id
    【解决方案2】:

    我也有同样的例外。

    当为类属性设置正确的关系时,我已经修复了它。 我无意中设置了@OneToOne 关系,并试图将其用作@ManyToOne。当我设置正确的关系时,问题就消失了。

    【讨论】:

      猜你喜欢
      • 2011-03-17
      • 1970-01-01
      • 2011-11-15
      • 1970-01-01
      • 2023-01-20
      • 1970-01-01
      • 2020-10-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多