Сохраняет ли hibernate порядок LinkedHashSet, и если да, то как? - PullRequest
14 голосов
/ 22 ноября 2010

Сохраняет ли hibernate порядок LinkedHashSet, и если да, то как? В случае, если это зависит от типа базы данных, я хотел бы знать это для PostgreSQL.

Справочная информация:

Я знаю, для чего нужен LinkedHashSet, и причина, по которой я спрашиваю об этом, заключается в том, что я записываю имена некоторых функций, которые я выполняю, в таблицу 'logError', которая имеет отношение многие ко многим к некоторым ' functionName 'таблица. Мне нужно, чтобы эти функции оставались в том же порядке, в котором я их выполнял, поэтому сначала я нахожу соответствующие объекты 'functionName', помещаю их в LinkedHashSet (после каждой сбойной функции), а затем сохраняю объект 'logError'.

Теперь, когда я снова получу объект 'logError' из базы данных, он все еще будет упорядочен? И если это так, мне было любопытно, как это делается в Hibernate.

Ответы [ 3 ]

13 голосов
/ 22 ноября 2010

Во-первых: я предполагаю, что вы говорите об отношениях между двумя сущностями. Что-то вроде

@Entity
public class A {
@ManyToMany
    @JoinTable(name = "A_B", joinColumns = { @JoinColumn(name = "A_fk") }, inverseJoinColumns = { @JoinColumn(name = "B_fk") })
    private Set<B> bSet = new LinkedHashSet<B>();
}

Hibernate не сохраняет заказ сам по себе!

Если вы посмотрите на классы, используемые при загрузке сущности A из базы данных, то Set bSet имеет тип PersistentSet, который является оберткой вокруг другого Set, и это является (в моем случае) нормальным HashSet. (HashSet не сохраняет порядок своих элементов.)

Даже если Hibernate использовал List или LinkedHashSet, все равно не рекомендуется основывать реализацию на естественном (не гарантированном) порядке базы данных. Для MySQL это своего рода анти-паттерн.

Но вы можете использовать аннотацию @Sort (org.hibernate.annotations.Sort), чтобы сделать вашу сортировку явной. Например:

@OneToMany(mappedBy = "as")
@Sort(type = SortType.COMPARATOR, comparator = MyBComparator.class);
public SortedSet<C> cs;

@ см .: Порядок возврата дочерних объектов в запросе JPA


Добавлено Łukasz Rzeszotarski 1 сентября 2012 г .:

Но мы должны помнить, что использование аннотации @Sort приводит к сортировке объектов в памяти (jvm), а не в sql. Вместо этого мы можем использовать аннотацию @OrderBy, которая вызывает сортировку на стороне сервера sql. Обе эти аннотации, по моему мнению (Лукаш Жешотарски), имеют одну слабость, которая устанавливает порядок по умолчанию. Я (Лукаш Жешотарский) предпочел бы использовать спящий режим, используя собственную реализацию LinkedHashSet, когда он «видит», что используется заказ order by.

@ см .: Спящий режим в sql

0 голосов
/ 25 декабря 2014

Когда мне нужно сохранить порядок списка элементов, я использую Map, а не List.

@OneToMany(fetch = FetchType.EAGER, mappedBy = "rule", cascade = CascadeType.ALL)
@MapKey(name = "position")
private Map<Integer, RuleAction>    actions             = LazyMap.decorate(new LinkedHashMap<>(), FactoryUtils.instantiateFactory(RuleAction.class, new Class[] { Rule.class }, new Object[] { this }));

В этом Java примере position является целочисленным свойством RuleAction, поэтому порядок сохраняется таким образом. Я предполагаю, что в C# это выглядело бы довольно похоже.

0 голосов
/ 22 ноября 2010

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

...