Поддерживается ли JPA @ManyToMany (mappedBy = ...) + @OrderColumn? - PullRequest
11 голосов
/ 31 марта 2012

У меня есть сущность, сопоставленная следующим образом:

@Entity
@Table(name = "Groups")
@IdClass(value = GroupId.class)
public class Group implements Serializable
{
    @Id
    @Column(name = "round_id")
    private Integer roundId;

    @Id
    @Column(name = "ordinal_nbr")
    private Integer ordinalNbr = 0;

    ...
}

Он имеет составной ключ (round_id, ordinal_nbr) для указания порядка групп в раунде.

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

CREATE TABLE GroupLinks
(
  parent_round_id INTEGER NOT NULL,
  parent_ordinal_nbr SMALLINT NOT NULL,
  child_round_id INTEGER NOT NULL,
  child_ordinal_nbr SMALLINT NOT NULL,
  PRIMARY KEY (parent_round_id, parent_ordinal_nbr, child_round_id, child_ordinal_nbr),
  FOREIGN KEY (parent_round_id, parent_ordinal_nbr) REFERENCES Groups (round_id, ordinal_nbr),
  FOREIGN KEY (child_round_id, child_ordinal_nbr) REFERENCES Groups (round_id, ordinal_nbr)
);

Я знаю, что можно сопоставить @ManyToMany + @JoinTable + @OrderColumn для объекта-владельца (что бы я ни выбрал):

@ManyToMany
@JoinTable(name = "GroupLinks", joinColumns = {@JoinColumn(name = "parent_round_id", referencedColumnName = "round_id"), @JoinColumn(name = "parent_ordinal_nbr", referencedColumnName = "ordinal_nbr")}, inverseJoinColumns = {@JoinColumn(name = "child_round_id", referencedColumnName = "round_id"), @JoinColumn(name = "child_ordinal_nbr", referencedColumnName = "ordinal_nbr")})
@OrderColumn(name = "child_ordinal_nbr")
private List<Group> children;

Вопрос:

Поддерживается ли принадлежащая сторона для сопоставления обратной связи @ManyToMany(mappedBy = ...) с @OrderColumn тоже?

@ManyToMany(mappedBy = "parents")
@OrderColumn(name = "parent_ordinal_nbr")
private List<Group> parents;

Определяет ли спецификация JPA 2, разрешать или запрещать это?

Спасибо


Обновление 1:

Выше приведена графическая структура. Вот пример:

image

Таблица GroupLinks содержит объекты в штучной упаковке. Если рассматривать только сущность B2 Group, список parents будет содержать (a,1,b,2) и (a,2,b,2). Что касается списка children, он будет содержать (b,2,c,1), (b,2,c,2) и (b,2,c,3).

Как вы можете видеть, объекты в списках B2 не будут сталкиваться, поэтому @OrderColumn должно нормально работать для обоих отношений parents и children - по крайней мере, в теории , Но что здесь за практика (JPA)?

Обратите внимание, что простое использование Hibernate и / или EclipseLink на самом деле не отвечает на вопрос, должна ли спецификация JPA 2 или JPA-совместимый поставщик поддерживать или поддерживать этот сценарий.


Обновление 2:

Попытка вышеуказанных сопоставлений в Hibernate приводит к следующему исключению сопоставления:

Caused by: org.hibernate.MappingException: Repeated column in mapping for collection: com.kawoolutions.bbstats.model.Group.parents column: parent_ordinal_nbr
    at org.hibernate.mapping.Collection.checkColumnDuplication(Collection.java:340)
    at org.hibernate.mapping.Collection.checkColumnDuplication(Collection.java:363)
    at org.hibernate.mapping.Collection.validate(Collection.java:320)
    at org.hibernate.mapping.IndexedCollection.validate(IndexedCollection.java:89)
    at org.hibernate.cfg.Configuration.validate(Configuration.java:1291)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1729)
    at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:84)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:904)
    ... 9 more

Удаление @OrderColumn для parent_ordinal_nbr приводит к тому же исключению для отношения children. Похоже, что Hibernate не любит столбцы заказов, которые также используются во внешних ключах.


Обновление 3:

Протестировано с EclipseLink на GlassFish ... это работает, без исключений для карт.

Это поднимает два последующих вопроса:

  1. Запрещает ли JPA столбцы порядка внешних ключей? Мне не имеет смысла, почему они не должны просто работать ...
  2. Это ошибка Hibernate?

Ответы [ 2 ]

8 голосов
/ 05 апреля 2012

Javadoc или OrderColumn содержит информацию, которую вы ищете:

Аннотация OrderColumn указывается на стороне отношения, которое ссылается на коллекцию, которая должна бытьприказал.Столбец порядка не отображается как часть состояния сущности или встраиваемого класса.

Аннотацию OrderBy следует использовать для упорядочивания, которое отображается как постоянное состояние и поддерживается приложением.Аннотация OrderBy не используется, если указан OrderColumn.

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

0 голосов
/ 08 августа 2013

В OPENJPA существует проблема, связанная с @OrderColumn, операция получения работает, но при сохранении сущности появляется ошибка «отсоединенный объект», эта ошибка связана с добавлением этой аннотации (@OrderColumn)

Решение состоит в том, чтобы использовать компаратор в классе parent.getChildEntity для упорядочения списка дочерних объектов, таким образом, это позволяет избежать использования @OrderColumn.

Collections.sort(this.child, new Comparator<class_type>() {
@Override
        public int compare(class_type p1, class_type p2) {
            return (int) (p1.getId() - p2.getId());
        }

    });

Решено :) John V, Col

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