hibernate: как сопоставить ассоциацию Set, чтобы порядок HQL сохранялся

Хорошо, это больше всего похоже на (еще одну) ошибку/нереализованную функциональность в Hibernate.

Можно ли отобразить ассоциацию Set таким образом, чтобы соблюдалось предложение "order by" в HQL?

Например, у вас есть 2 сущности: PageEntity и QuestionEntity. Страница имеет Set.

Как заставить работать следующий HQL:

from
    PageEntity p
        left outer join fetch p.questionEntities q
order by
    q.orderIndex

Чего я не хочу:

  • использовать сортировку в Java (у нас есть «упорядочение по» в SQL, поэтому нам не нужно этого делать!). SortedSet, компараторы и т. д. не могут быть и речи
  • чтобы отобразить его как список с <list-index>. Это добавит «порядок» ко всем SQL-запросам, и я не хочу этого
  • использовать <set order-by="orderIndex">, потому что, опять же, это будет применяться ко всем запросам

При отладке я вижу, что используемая реализация Set — это org.hibernate.collection.PersistentSet, которая обертывает Set. Реализация обернутого Set — это HashSet. Я ожидаю, что Hibernate будет достаточно умен, чтобы использовать вместо этого LinkedHashSet, чтобы он мог соблюдать мое предложение HQL «order by».


person Cristian Vasile Mocanu    schedule 13.09.2011    source источник


Ответы (3)


Я почти уверен, что Hibernate не может сделать это за вас, и вместо этого рекомендовал бы использовать List. Чтобы удалить дубликаты, созданные объединением, вы можете использовать distinct. Полученный List будет так же хорош, как и любой Set.

Если они вам все еще нужны в упорядоченном Set (возможно, задействован сторонний API), вы можете создать свой собственный LinkedHashSet и переместить туда все объекты:

List<PageEntity> list = runQuery(...);
return new LinkedHashSet<PageEntity>(list);
person Martin    schedule 13.09.2011

Кажется, вы хотите получить результаты, отсортированные по q.orderIndex, но

  • Вы хотите, чтобы результирующий список PageEntity был отсортирован?
  • или (как я думаю) вы хотите, чтобы набор QuestionEntitys для каждого PageEntity был отсортирован?

Если вы хотите последнее: Set в Java не сохраняют порядок.

После вашего редактирования: никакой Hibernate не должен быть умным: если вы определите свою коллекцию как Set, она будет рассматриваться как набор. Есть много приложений, где сохранение порядка стоит ресурсов и не нужно.

person Matteo    schedule 13.09.2011
comment
Таким образом, нет способа контролировать, когда ассоциация упорядочивается в зависимости от порядка по предложению HQL? - person Cristian Vasile Mocanu; 13.09.2011
comment
Есть способ заказать сет. Спецификации Java ясно говорят, что использование Set порядка не гарантируется. Если вы повторяете набор, вы можете получить элемент в любом порядке. - person Matteo; 13.09.2011
comment
Спецификации также говорят, что порядок итераций для LinkedHashSet всегда стабилен. - person Cristian Vasile Mocanu; 14.09.2011
comment
Да нигде не указано, что Hibernate PersistentSet должен быть LinkedHashSet. См. stackoverflow.com/questions/4243865/ - person Matteo; 14.09.2011

order by применяется к результатам запроса. Не к сущностям в наборе вопросов. Я не думаю, что это ошибка: что бы он сделал, если бы один из возвращаемых объектов страницы уже был загружен в сеансе, используя другой запрос с другим предложением order by?

Если вам нужен упорядоченный список вопросов, выберите вопросы:

select q from QuestionEntity q inner join fetch q.page p order by q.orderIndex

or

select p, q from PageEntity p
left outer join fetch p.questionEntities q 
order by q.orderIndex

должен сделать трюк.

person JB Nizet    schedule 13.09.2011