2015-07-02 2 views
3

Error: org.hibernate.exception.ConstraintViolationException: Не удалось выполнить JDBC пакетного обновленияorg.hibernate.exception.ConstraintViolationException: Не удалось выполнить JDBC пакетное обновление [Из-за уникального ограничения]

java.sql .BatchUpdateException: Дублировать запись '24 -0-es_reservation_detail 'для ключа' questionId_referenceId_referenceType '

Я собираюсь сохранить объект резервирования. Этот объект резервирования содержит коллекцию объектов reserveaitonDetails и каждый объект детали резервирования содержит коллекцию questionAnswers Objects.

Основной проблемой является ограничение уникальности на QuestionAnswer таблице

Unqiue Constraint: question_id, reference_id, reference_type. 

Когда система сохранения объекта резервирования: система сначала сохранить резервирование, а затем сбор деталей бронирования, а затем все его ответы вопрос с 0 (REFERENCE_ID). Добавляя вопрос с 0 ссылочным идентификатором, система выдает исключение, поскольку нарушается уникальное ограничение.

ReservationDetail.hbm.xml

............. 
............. 
<set name="questionAnswers" lazy="true" cascade="all-delete-orphan" where="reference_type = 'es_reservation_detail'"> 
     <key column="reference_id"/> 
     <one-to-many class=".....QuestionAnswerDTO" /> 
    </set> 
............. 
............. 

Пример:

Если сохранить коллекцию на детали бронирования

1. insert into reservation......... (reservation id = 1) 

2. insert into reservation_detail....... (reservation detail id = 1) 
3. insert into reservation_detail....... (reservation detail id = 2) 

4. insert into question_answer..... (referece_type='RD' referece_id=0, question_id =1) - For Reservation Detail id = 1 
5. insert into question_answer..... (referece_type='RD' referece_id=0, question_id =1) - For Reservation Detail id = 1 

6. update reservation_detail set reservation_id = ? where reservation_detail_id = ? (reservation_id = 1, reservation_detail_id = 1) 
7. update reservation_detail set reservation_id = ? where reservation_detail_id = ? (reservation_id = 1, reservation_detail_id = 2) 

8. update question_answer set reference_id = ? where question_answer_id = ? (reference_id = 1 and question_answer_id =1) 
9. update question_answer set reference_id = ? where question_answer_id = ? (reference_id = 2 and question_answer_id =2) 

Когда система будет выполнять пункт (5) сценарий. Исключением является нарушение ограничений.

Есть ли способ спячки обновить reference_id в question_answer (table) непосредственно перед созданием следующего запроса вставки.

Сценарий 8 должен работать после 4-го сценария

Сценарий 9 должен работать после 5-го сценария

+0

Какой тип генератора вы используете, кажется, что идентификатор не увеличивается, на вопросе и ссылочном объекте –

+0

Как я читал документы спящего режима. Hibernate сначала вставляет дочерние объекты (questionAnswer) с нулевой или 0 ссылкой, а затем hibernate выполняет запрос на обновление (см. Сценарий 8 и 9). –

+0

два разных объекта не могут иметь одинаковый идентификатор, я не знаю, где вы получили точку, является вопросом_ид, а reference_id - составными ключами? –

ответ

1

Hiberate cascade опция вставить дочерние объекты с внешним ключом, если вы правильно сопоставили родительский класс при отображении дочерних элементов. Если вы не сопоставляется родительского класса в отображении ребенка, но, как Integerreference_id, то внешний ключ будет обновляться с помощью отдельного запроса на обновление:

update question_answer set reference_id = ? where question_answer_id = ? 

Если вы не можете указать родительский объект класса в отображении ребенка, то вы можете использовать обходной путь ,Вы можете установить reference_id как null разрешено (на столе), и вам нужно установить referenceId=null; в дочерний объект. Затем каскад Hibernate будет вставлять дочерние объекты, будет null внешний ключ и следующий запрос на обновление запроса для установки referenceId сгенерированного внешнего ключа.

Примечание: null значения в уникальной колонке не рассматриваются как повторяющиеся значения, если они появляются более одного раза.

1

Скорее всего, вы не определили в QuestionAnswerDTO сущности ссылку назад к основной сущности, которая ReservationDetails , Вы должны настроить @ManyToOne в QuestionAnswerDTO, который имеет, как @JoinColumn «REFERENCE_ID» что-то вроде этого

@ManyToOne 
@JoinColumn(name="persistence_id") 
private ReservationDetail reservationDetail; 

, а затем установить reservationDetail свойство реального объекта ReservationDetail, к которому он принадлежит.

Тогда JPA будет знать, что ему необходимо заполнить reference_id ссылкой на REservationDetails. В противном случае он считает это как любое другое поле

+0

В основном проблема с ссылкой отсутствует. Эта проблема идет с последовательностью скриптов, создаваемых спящим режимом. Мне нужно обновить идентификатор ссылки сразу после вставки. Но hibernate генерирует сценарии обновления после всех вставок (как упоминалось в вопросе.) –

+0

hibernate генерирует сценарии на основе ваших конфигураций сущностей и отношений между ними. Пока вы правильно настраиваете все отношения, вам не нужно вмешиваться в то, что Hibernate делает на уровне SQL. Hibernate будет генерировать сценарии таким образом, чтобы оптимизировать взаимодействие с базой данных. – iullianr

Смежные вопросы