0

美好的一天人们。

我试图弄清楚如何处理休眠。在我的测试中,我使用 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;
        }

}

使用 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 是每个子类继承的表。

数据库中的 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

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

<generator class="native"/>

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

也是因为下面的代码

dao.saveUser(1, eventsList);

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

于 2013-10-07T11:39:09.500 回答
0

我也有同样的例外。

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

于 2014-03-15T22:01:02.640 回答