Подтвердить что ты не робот

Сохраняет ли hibernate порядок LinkedHashSet, и если да, то как?

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

Фон:

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

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

4b9b3361

Ответ 1

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

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

Спящий режим не сохраняет порядок сам по себе!

Если вы посмотрите на классы, используемые при загрузке объекта 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;

@see: Заказ возврата дочерних объектов в запрос JPA


Добавил (а) Łukasz Rzeszotarski 1 сентября 2012:

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

@see: Заказ Hibernate в sql

Ответ 2

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

Ответ 3

Когда мне нужно сохранить порядок списка элементов, я использую 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 является свойством Integer RuleAction, поэтому порядок сохраняется таким образом. Я думаю, что в C# это выглядело бы довольно похоже.