java - org.hibernate.exception.ConstraintViolationException : Could not execute JDBC batch update

标签 java mysql hibernate mysql-error-1062

虽然数据已成功插入,但我得到了下面提到的堆栈跟踪。

Hibernate: select attendee_.attendeeId, attendee_.attendeeName as attendee2_1_ from attendee attendee_ where attendee_.attendeeId=?
Hibernate: select attendee_.attendeeId, attendee_.attendeeName as attendee2_1_ from attendee attendee_ where attendee_.attendeeId=?
Hibernate: insert into event (eventName, startDate, eventId) values (?, ?, ?)
Hibernate: insert into attendee (attendeeName, attendeeId) values (?, ?)
Hibernate: insert into attendee (attendeeName, attendeeId) values (?, ?)
Hibernate: update attendee set attendeeId=? where attendeeId=?
Hibernate: update attendee set attendeeId=? where attendeeId=?
Aug 29, 2010 7:39:10 PM org.hibernate.util.JDBCExceptionReporter logExceptions
WARNING: SQL Error: 1062, SQLState: 23000
Aug 29, 2010 7:39:10 PM org.hibernate.util.JDBCExceptionReporter logExceptions
SEVERE: Duplicate entry '11' for key 'PRIMARY'
Aug 29, 2010 7:39:10 PM org.hibernate.event.def.AbstractFlushingEventListener performExecutions
SEVERE: Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:69)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:202)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:230)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:144)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:296)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:980)
    at com.practice.hibernate.basic.BasicOperations.main(BasicOperations.java:51)
Caused by: java.sql.BatchUpdateException: Duplicate entry '11' for key 'PRIMARY'
    at com.mysql.jdbc.ServerPreparedStatement.executeBatch(ServerPreparedStatement.java:665)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:195)
    ... 6 more
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:69)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:202)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:230)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:144)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:296)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:980)
    at com.practice.hibernate.basic.BasicOperations.main(BasicOperations.java:51)
Caused by: java.sql.BatchUpdateException: Duplicate entry '11' for key 'PRIMARY'
    at com.mysql.jdbc.ServerPreparedStatement.executeBatch(ServerPreparedStatement.java:665)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:195)
    ... 6 more

请注意:

a) 我的数据库目前没有记录 b) 数据成功插入DB。

在这里,我试图保留一个包含两个参加者对象的事件对象。就是这样。

我的测试类:

public static void main(String[] args) {
    Session session = HibernateRuntime.getSession();

    try {
        Set<Attendee> attendees = new HashSet<Attendee>(2);

        Attendee attendee = new Attendee();
        attendee.setAttendeeId(3);
        attendee.setAttendeeName("Baswanth Rao");

        Attendee attendee1 = new Attendee();
        attendee1.setAttendeeId(4);
        attendee1.setAttendeeName("Razi Ahmed");

        attendees.add(attendee);
        attendees.add(attendee1);

        Event event = new Event();
        event.setEventId(11);
        event.setEventName("Initiatives Workshop 3");
        event.setStartDate(new Date());
        event.setAttendees(attendees);

        session.save(event);
        session.flush();

    } finally {
        session.close();
    }
}

事件.hbm.xml:

<hibernate-mapping package="com.practice.hibernate.vo">
    <class name="Event" table="event">
        <id name="eventId" column="eventId" type="long">
            <generator class="assigned" />
        </id>

        <property name="eventName" type="string" length="100" />
        <property name="startDate" type="date" />

        <set name="attendees" cascade="all">
            <key column="attendeeId" />
            <one-to-many class="Attendee" />
        </set>
    </class>
</hibernate-mapping>

hibernate .cfg.xml

<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost/test</property>
        <property name="connection.username">root</property>
        <property name="connection.password"></property>
        <property name="connection.autocommit">false</property>

        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="show_sql">true</property>

        <mapping resource="com/practice/hibernate/vo/Event.hbm.xml"></mapping>
        <mapping resource="com/practice/hibernate/vo/Attendee.hbm.xml"></mapping>
    </session-factory>
</hibernate-configuration>

最佳答案

你的 Event.hbm.xml 说:

<set name="attendees" cascade="all">
    <key column="attendeeId" />
    <one-to-many class="Attendee" />
</set>

用简单的英语来说,这意味着 Attendee.attendeeId 列是关联 attendees外键并指向主键事件

当您将这些参加者添加到事件中时, hibernate 更新外键以表示更改后的关联。由于同一列也是 Attendee 的主键,这违反了主键约束。

由于参加者的身份和 Activity 参与是独立的,因此您应该为主键和外键使用单独的列。

编辑:选择可能是因为您似乎没有配置版本属性,使 hibernate 无法知道与会者是否已存在于数据库中(他们可能已在之前的 session 中加载),所以 hibernate 发出选择来检查。至于更新语句,以这种方式实现可能更容易。如果您想摆脱这些单独的更新,我建议从两端映射关联,并将 Event-end 声明为 inverse

关于java - org.hibernate.exception.ConstraintViolationException : Could not execute JDBC batch update,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3595065/

相关文章:

php - MySQL 全文搜索 - 数值和 ft_min_word_len 的解决方法

java - Spring JPA : Insert new Entity and Cascade detached Reference

java - H2 控制台在 H2 数据库中抛出错误 webAllowOthers

mysql - 如何在 JPA 中使用一个查询更新 3 个表?

php - Word/Doc/Pdf 文件到 csv 文件格式

mysql - org.springframework.web.multipart.MultipartException : Current request is not a multipart request

java - 在 hibernate 条件中使用 sum

java - 类型 new MediaPlayer.OnCompletionListener(){} 必须实现继承的抽象方法

JavaMail smtp 属性(用于 STARTTLS)

java - 无法在Android中播放Telegram Ogg音频文件