虽然成功插入了数据,但我得到了下面提到的堆栈跟踪。
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。
这里我试图坚持一个包含两个参加者对象的Event对象。就是这样。
我的测试类:
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>
答案 0 :(得分:13)
您的Event.hbm.xml说:
<set name="attendees" cascade="all">
<key column="attendeeId" />
<one-to-many class="Attendee" />
</set>
简单来说,这意味着列Attendee.attendeeId
是关联attendees
的外键,并指向Event
的主键。
当您将这些参加者添加到事件时,hibernate会更新外键以表示更改的关联。由于同一列也是参加者的主键,因此违反了主键约束。
由于参加者的身份和事件参与是独立的,因此您应该为主键和外键使用单独的列。
编辑:选择可能是因为您似乎没有配置版本属性,因此hibernate无法知道参与者是否已经存在于数据库中(他们可能已在前一个会话中加载),因此hibernate发出选择检查。至于更新语句,实现这种方式可能更容易。如果您想摆脱这些单独的更新,我建议从两端映射关联,并声明Event
- 结束为inverse
。
答案 1 :(得分:2)
您可以在此处完整找到示例代码: http://www.java2s.com/Code/Java/Hibernate/OneToManyMappingbasedonSet.htm
看看并检查差异。特别是even_id in:
<set name="attendees" cascade="all">
<key column="event_id"/>
<one-to-many class="Attendee"/>
</set>
答案 2 :(得分:-3)
您可能需要处理javax.persistence.RollbackException