org.hibernate.exception.ConstraintViolationException:无法执行 JDBC 批量更新
尽管数据已成功插入,但我得到了下面提到的堆栈跟踪。
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) 数据成功插入数据库。
在这里,我尝试保留一个包含两个参加者对象的事件对象。仅此而已。
我的测试类:
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();
}
}
Event.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>
I get below mentioned stack trace though the data gets inserted successfully.
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
Please note:
a) My db has no records currently
b) Data gets inserted into DB successfully.
Here I am trying to persist an Event object which contains two Attendee Objects. That is all.
My Test Class:
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();
}
}
Event.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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(3)
Smile简单爱2024-09-23 13:53:14
您可以在这里找到完整的示例代码:
http://www.java2s.com/Code/Java/Hibernate/OneToManyMappingbasedonSet。 htm
看一下并检查差异。特别是中的 Even_id :
<set name="attendees" cascade="all">
<key column="event_id"/>
<one-to-many class="Attendee"/>
</set>
~没有更多了~
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
您的 Event.hbm.xml 表示:
用简单的英语来说,这意味着
Attendee.attendeeId
列是关联attendees
的外键,并且指向Event
的主键。当您将这些参加者添加到事件中时,hibernate 会更新外键以表达更改后的关联。由于同一列也是参加者的主键,因此这违反了主键约束。
由于参加者的身份和活动参与是独立的,因此您应该对主键和外键使用单独的列。
编辑:选择可能是因为您似乎没有配置版本属性,使得休眠无法知道与会者是否已存在于数据库中(它们可能已在上一个会话中加载),因此休眠会发出选择检查。至于更新语句,这种方式可能更容易实现。如果您想摆脱这些单独的更新,我建议从两端映射关联,并将
Event
-end 声明为inverse
。Your Event.hbm.xml says:
In plain english, this means that the column
Attendee.attendeeId
is the foreign key for the associationattendees
and points to the primary key ofEvent
.When you add those Attendees to the event, hibernate updates the foreign key to express the changed association. Since that same column is also the primary key of Attendee, this violates the primary key constraint.
Since an Attendee's identity and event participation are independent, you should use separate columns for the primary and foreign key.
Edit: The selects might be because you don't appear to have a version property configured, making it impossible for hibernate to know whether the attendees already exists in the database (they might have been loaded in a previous session), so hibernate emits selects to check. As for the update statements, it was probably easier to implement that way. If you want to get rid of these separate updates, I recommend mapping the association from both ends, and declare the
Event
-end asinverse
.