Подтвердить что ты не робот

Аннотация @OrderColumn в Hibernate 3.5

Я пытаюсь использовать аннотацию @OrderColumn Hibernate 3.5

@OneToMany(mappedBy = "parent",fetch=FetchType.EAGER, cascade=CascadeType.ALL)
@OrderColumn(name = "pos")
private List<Children> childrenCollection;

При получении данных все работает отлично. Но я не могу изменить порядок элементов в списке и сохранить новый порядок в базе данных.

4b9b3361

Ответ 1

Комбинация @OneToMany (mappedBy = "..." ) и @OrderColumn не поддерживается Hibernate. Эта проблема JIRA отслеживает запрос на получение более очевидного сообщения об ошибке при использовании этой недопустимой комбинации: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5390

Я думаю, что это не поддерживается главным образом потому, что это нечетный реляционный шаблон. Аннотации, приведенные выше, указывают, что "одна" сторона отношения определяет, как отношения будут очищаться от базы данных, но порядок/позиция доступны только на стороне "многих", изучая список. Для "многих" сторон имеет смысл владеть отношениями, поскольку эта сторона знает как членство, так и порядок элементов.

В аннотациях Hibernate подробно описывается эта ситуация:

http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#entity-hibspec-collection-extratype-indexbidir

Обходной путь заключается в удалении атрибута "mappedBy", который заставит ассоциацию использовать стратегию таблицы соединений по умолчанию вместо столбца целевой таблицы. Вы можете указать имя таблицы соединений, используя аннотацию @JoinTable.

Чистый эффект этого изменения заключается в том, что "многие" стороны отношения теперь определяют, как сохраняется связь. В вашем Java-коде необходимо убедиться, что список обновлен правильно, потому что Hibernate теперь игнорирует "одну" сторону при очистке объектов.

Если вы все еще хотите иметь "одну" сторону, доступную в Java, сопоставьте ее с помощью

@ManyToOne
@JoinColumn(name="...", insertable=false, updatable=false, nullable=false)

Ответ 2

Сделайте что-то вроде этого:

@Entity
class Parent {

    @OneToMany
    @OrderColumn(name = "pos")
    List<Child> children;
}

@Entity
class Child {

    @ManyToOne
    Parent parent;
    @Column(name = "pos")
    Integer index;

    @PrePersist
    @PreUpdate
    private void prepareIndex() {
        if (parent != null) {
            index = parent.children.indexOf(this);
        }
    }
}

Ответ 3

Вам следует попытаться указать OrderColumn на владельца ассоциации. Или в вашем сопоставлении вы кладете владельца на ребенка, владелец должен быть родителем (при двунаправленной ассоциации владелец - тот, у которого нет ключевого слова mappedBy, здесь вы помещаете это ключевое слово в родительский класс, тогда вы означает, что родительский класс не является владельцем)

В классе ваших детей должно быть указано ключевое слово mappedBy на parentCollection. Но не на childrenCollection.
И в вашем родительском классе вы должны иметь аннотацию @JoinTable, что-то вроде этого:

@OneToMany(mappedBy = "parent",fetch=FetchType.EAGER, cascade=CascadeType.ALL)
@OrderColumn(name = "pos")
@JoinTable( name = "<NAME_OF_YOUR_TABLE>", joinColumns = @JoinColumn( <JOIN_COLUMNS_...> )
private List<Children> childrenCollection;