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) Моят db няма записи в момента b) Данните се вмъкват успешно в DB.

Тук се опитвам да запазя обект Event, който съдържа два обекта Attendee. Това е всичко.

Моят тестов клас:

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>

person Bashu    schedule 29.08.2010    source източник
comment
премахнете зависимостта от Attendee и опитайте отново. или проверете отново вашия Attendee.hbm.xml   -  person mhshams    schedule 29.08.2010
comment
сигурни ли сте, че тестовият код се изпълнява само 1 път? можете да поставите някакъв журнал в основния си метод, за да сте сигурни, че току-що е изпълнил един елемент.   -  person mhshams    schedule 29.08.2010
comment
Башу, използвай връзката за редактиране, за да добавиш това към въпроса. Намира се в долния ляв ъгъл на текста на вашия въпрос, точно под бутона за тага за хибернация.   -  person meriton    schedule 29.08.2010


Отговори (3)


Вашият Event.hbm.xml казва:

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

На обикновен английски това означава, че колона Attendee.attendeeId е чуждият ключ за асоциацията attendees и сочи към първичния ключ на Event.

Когато добавите тези присъстващи към събитието, hibernate актуализира външния ключ, за да изрази променената асоциация. Тъй като същата колона е и първичен ключ на Attendee, това нарушава ограничението на първичния ключ.

Тъй като самоличността на присъстващия и участието в събитието са независими, трябва да използвате отделни колони за първичния и външния ключ.

Редактиране: Изборите може да са, защото изглежда, че нямате конфигурирано свойство за версия, което прави невъзможно за hibernate да разбере дали присъстващите вече съществуват в базата данни (те може да са били заредени в предишна сесия), така че hibernate излъчва селекти да проверя. Що се отнася до изявленията за актуализиране, вероятно беше по-лесно да се приложи по този начин. Ако искате да се отървете от тези отделни актуализации, препоръчвам да картографирате асоциацията от двата края и да декларирате Event-край като inverse.

person meriton    schedule 29.08.2010
comment
да, това е проблемът, трябва да имате друга колона във вашата таблица на участниците - person mhshams; 29.08.2010
comment
Да... благодаря Меритън. Проблемите вече са разрешени... Съжалявам, че това беше основен проблем, трябваше да го проверя старателно, може би. - person Bashu; 29.08.2010
comment
Бихте ли могли също да обясните защо се изпълняват първите 2 селекции и последните 2 актуализации. Не можем ли да избегнем тези две изявления за актуализиране? - person Bashu; 29.08.2010

Можете да намерите целия си примерен код тук: 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> 
person mhshams    schedule 29.08.2010

Може да се наложи да обработите javax.persistence.RollbackException

person waqar    schedule 22.07.2013