views:

41

answers:

2

Hi Friends,

I am new to this forum. I am facing a strange problem. 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 the below things

a) My db has no records currently b) Data gets inserted into DB successfully.

Im sorry if this is a basic problem

Here i am trying to persist an Event object which contains two Attendee Objects. Thats all.

My Test Calss:

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>
+1  A: 

Your Event.hbm.xml says:

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

In plain english, this means that the column Attendee.attendeeId is the foreign key for the association attendees and points to the primary key of Event.

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 as inverse.

meriton
yeah, that is the issue, you should have another column in your Attendee table
mohammad shamsi
Yeah... thanks Meriton. The issues is resolved now... I am sorry this was a basic problem, i should have verified it thoroughly may be.
Bashu
Could you pls also explain why the first 2 selects and last 2 updates are executed. Cant we avoid these two update statements?
Bashu
A: 

you can find your sample code completely here: http://www.java2s.com/Code/Java/Hibernate/OneToManyMappingbasedonSet.htm

have a look and check the differences. speciall the even_id in :

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