2010-06-02 2 views
21

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

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

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

+0

Можете ли вы показать, как вы изменить порядок списка и сохранить вернуться в базу данных ??? –

+0

Я попытался создать новый ArrayList и parent.setChildrenCollection (newList) Я пробовал Collections.sort по извлеченному списку. Я также пытался удалить ненужные элементы из коллекции. Ничего не произошло. Другие каналы в родителе были сохранены в базе данных, но ничего не произошло со списком. –

+0

не Hibernate 3.5 для JPA 1.0, а @OrderColumn - JPA 2.0 ?! –

ответ

25

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

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

The 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) 
+4

Забавно, что «официальный» пример для явных столбцов индекса использует именно комбинацию '@OneToMany (mappedBy =" ... ")' + '@ OrderColumn' (см. Пример 7.8 в http: //docs.jboss.org/hibernate/core/3.6/reference/en-US/html/collections.html # collections-indexed) –

+2

После этого ответа было решено, что ситуация должна поддерживаться в любом случае. Гейл Баднер: «Я согласен с тем, что @OneToMany (mappedBy =« ... ») должен поддерживаться». –

+1

Есть ли еще один поставщик JPA (например, Eclipselink), который поддерживает '@OneToMany (mappedBy =" ... ")'? – deamon

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; 
9

что-то вроде этого:

@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); 
     } 
    } 
} 
+2

Я думаю, что в prepareIndex() он должен быть изменен на index = parent.children.indexOf (this); if (index == -1) index = parent.children.size(); – cn123h

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