Аннотация @OrderColumn в Hibernate 3.5 - PullRequest
23 голосов
/ 02 июня 2010

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

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

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

Ответы [ 3 ]

26 голосов
/ 14 августа 2010

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

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

Документы Hibernate Annotations описывают эту ситуацию более подробно:

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)
9 голосов
/ 19 сентября 2012

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

@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 голосов
/ 08 сентября 2011

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

В вашем классе детей у вас должно быть ключевое слово mappedBy для parentCollection. Но не на детей. Коллекция.
И в вашем родительском классе у вас должна быть аннотация @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;
...