0

こんばんは。

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

私は 2 つの親エンティティを持っています。1 つ目は、サブクラス 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;
        }

}

userevent の xml マッピングを使用:

<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 エンティティ + サブクラス = 継承 階層ごとのテーブル:

+----+----------------------------+------------+-----------+----------+-----------------+--------+--------------------+------------------+
| 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             |
+----+----------------------------+------------+-----------+----------+-----------------+--------+--------------------+------------------+

UserEvents とサブクラスの間: SoftwareDevelopmentEvent と ComputerMaitnanceEvent は、サブクラス継承ごとのテーブルです。

DB の 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" を誤ってリレーションシップに設定してしまいました。

みんなありがとう。

4

2 に答える 2

0

私にも同じ例外がありました。

クラス属性に正しい関係を設定すると修正されました。@OneToOne 関係を誤って設定し、それを @ManyToOne として使用しようとしました。正しい関係を設定すると、問題はなくなりました。

于 2014-03-15T22:01:02.640 に答える