Сохраняет ли hibernate порядок LinkedHashSet, и если да, то как?
сохраняет ли hibernate порядок LinkedHashSet, и если да, то как? Если это зависит от типа базы данных, я хотел бы знать это для PostgreSQL.
Справочная информация:
Я знаю, что LinkedHashSet, и причина, по которой я спрашиваю это потому, что я захожу названия некоторых функций я выполняю на logError стол, который имеет многие-ко-многим отношению к некоторым 'имя_функции' таблица. Мне нужно, чтобы эти функции оставались в том же порядке, что и когда Я выполнил их, поэтому сначала я нахожу соответствующие объекты "functionName", помещаю их в LinkedHashSet (после каждой функции, которая не удалась), а затем сохраняю объект "logError".
теперь, когда я снова получу объект logError из базы данных, он все равно будет заказан? И если да, то мне было любопытно, как это делается Hibernate.
3 ответов
во-первых: я предполагаю, что вы говорите о связи между двумя сущностями. Что-то вроде
@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 не сохраняет порядок сам по себе!
если вы посмотрите на классы, используемые при entity 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 query
добавлено Łukasz Жешотарский 1 сентября 2012 года:
но мы должны помнить, что с помощью @Sort
аннотация вызывает сортировку объектов в памяти (jvm), а не в sql. Вместо этого мы можем использовать @OrderBy
аннотация, которая вызывает сортировку на стороне sql server. Обе эти аннотации имеют, по моему мнению (Лукаш Жешотарский), одну слабость, которая устанавливает порядок по умолчанию. I (Łukasz Rzeszotarski ) предпочел бы использовать собственную реализацию LinkedHashSet, когда он "видит", что предложение order by предназначенный.
наборы не имеют присущего "порядка", как и таблицы базы данных - вы можете применить порядок при запросе данных, но если вы не сохраните этот порядок (например, получая строки один за другим и помещая их в упорядоченный контейнер, как связанный список), то возвращаемые данные также будут неупорядоченными.
когда мне нужно сохранить порядок списка элементов, я использую 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#
это будет выглядеть довольно похожие.