Порядок гибернации [update, delete] для коллекции нарушает ограничение БД. Как исправить? - PullRequest
1 голос
/ 19 августа 2011

Hibernate вызывает боль при слиянии объекта, который содержит упорядоченную коллекцию, при удалении элемента из середины коллекции.

Некоторые предыстории: я работаю над инструментом, который создает отчеты CSV. В моей модели я хочу, чтобы у объекта отчета были объекты столбцов, порядок которых определяется значением столбца int.

Проблема возникает, когда я удаляю столбец, у которого orderIndex не последний в списке. При выполнении merge () Hibernate запускает следующий SQL:

update REPORT_COLUMNS set [...], orderIndex=1 where pkey=2 --This is formerly the 2nd column, and now it's orderIndex is going to collide with the orderIndex of the 1st 
delete from REPORT_COLUMNS where pkey=1 --This is the 1st column, which is being removed

Если бы Hibernate запустил удаление первым, проблем не было бы.

Вот как объявляется коллекция:

@OneToMany(fetch = FetchType.EAGER)
@Fetch(value = FetchMode.SUBSELECT)
@OrderBy("orderIndex")
@JoinColumn(name = "report", updatable = true, insertable = true, nullable = false)
@Cascade({ org.hibernate.annotations.CascadeType.DELETE,
    org.hibernate.annotations.CascadeType.DELETE_ORPHAN,
    org.hibernate.annotations.CascadeType.MERGE,
    org.hibernate.annotations.CascadeType.PERSIST,
    org.hibernate.annotations.CascadeType.REMOVE,
    org.hibernate.annotations.CascadeType.SAVE_UPDATE })
public List<ReportColumnImpl> getColumnImpls() {
    return columns;
}

Ваша помощь будет принята с благодарностью.

Ответы [ 2 ]

0 голосов
/ 19 августа 2011

Вам нужно обновить indexindex?

эта коллекция целых чисел (1, 2, 3, 4, 5, 6, 7) все еще может быть отсортирована в том же порядке, если вы удалили 1 или несколько элементов. например,

(1, 2, 5, 7)

если вам нужно поддерживать порядок, почему бы не создать ReportColumn, в котором хранятся ссылки на следующий и предыдущий столбец (во многом как связанный список), а затем при удалении одного из них обновить элементы по обе стороны от него?

0 голосов
/ 19 августа 2011

Самое простое решение - сделать ограничение отложенным, то есть проверяться только в конце транзакции. Oracle поддерживает отложенные ограничения. Не знаю о вашей базе данных.

Иначе, вы можете удалить сущность для удаления, затем очистить сеанс, а затем обновить indexIndexes. Но у вас также могут возникнуть проблемы, если Hibernate пытается обновить индекс 4-го элемента перед обновлением индекса 3-го.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...