Hibernate: заказ набора - PullRequest
       12

Hibernate: заказ набора

13 голосов
/ 01 апреля 2010

У меня есть класс Person, у которого есть набор Книг. В конкретном случае не имеет смысла иметь упорядоченную или отсортированную коллекцию.

Скажем, теперь у меня есть страница поиска с таблицей, показывающей соединение Персоны и Книги. Я хочу иметь возможность сортировать результаты по полям из Person и Book, а затем получать список из Hibernate и перебирать его.

Поскольку коллекция является Набором, порядок Книг исчез.

Итак, при таком подходе у меня не может быть результатов, упорядоченных по полям Книги.

Если я поменяю коллекцию с Set на List, моя модель семантически неверна. Нет смысла поддерживать порядок в модели.

Есть ли подход, чтобы сохранить порядок Книг? Возможно, у PersistentSet есть способ обернуть LinkedHashSet (который упорядочен), где порядок определяется моими критериями поиска?

Ура! * * 1013

Ответы [ 4 ]

7 голосов
/ 01 апреля 2010

Hibernate поддерживает отображение коллекции как SortedSet. В ваших сопоставлениях вам просто нужно указать предложение order-by. Взгляните на эту главу в справочном руководстве .

4 голосов
/ 25 сентября 2012

Как сказал Маркос Фрагкакис

к сожалению, упорядочение в отображении (или @OrderBy) имеет приоритет, что делает упорядочивание, установленное критериями, бесполезным.

Но вы должны установить @Order, если хотите, чтобы набор был заказан.

Вместо этого вы все равно можете использовать HQL (протестирован на hibernate 3.3.2.GA), который упорядочивает сначала по порядку в запросе hql:

    @Entity
    @Table(name = "Person")
    public class Person  {

        @Id
        @Column(name = "ID_PERSON", unique = true, nullable = false, precision = 8, scale = 0)
        private Long id;

        @OneToMany(fetch = FetchType.LAZY, mappedBy = "person")
        @OrderBy
        private Set<Book> books = new HashSet<Book>(0);

        public Person() {
        }

        public Long getId() {
            return this.id;
        }

        public void setId(Long id) {
            this.id = id;
        }


      public Set<Book> getBooks() {
            return this.books;
        }

        public void setBooks(Set<Book> books) {
            this.books = books;
        }

    }

      /** 
       *  hql Version 
       *    
       *  Result in : 
       *  order by
       *      book1_.TITLE asc,
       *      book1_.ID_BOOK asc  
       **/

        @Override
        public Person getFullPerson(Long idPerson) {

            StringBuilder hqlQuery =  new StringBuilder();
            hqlQuery.append("from Person as p ");
            hqlQuery.append("left join fetch p.books as book ");
            hqlQuery.append("where p.id = :idPerson ");
            hqlQuery.append("order by book.title ");
            Query query = createQuery(hqlQuery.toString());
            query.setLong("idPerson", id);
            return uniqueResult(query);

        }




      /** 
       *  criteria  Version // not usable 
       *    
       *  Result in : 
       *  order by
       *      book1_.ID_BOOK asc,
       *      book1_.TITLE asc  
       **/

      @Override
    public Person getFullPersonCriteria(Long idPerson) {

        Criteria criteria = ...
        criteria.add(Restrictions.eq("id", idPerson));
        criteria.createAlias("books", "book", CriteriaSpecification.LEFT_JOIN);
        criteria.addOrder(Order.asc("book.title"));
            return criteria.uniqueResult();
      }
3 голосов
/ 01 августа 2013

Это сортировка в памяти, которая позаботится о дубликатах в таблице соединений.

  @OneToMany
  @JoinTable(name = "person_book", joinColumns = @JoinColumn(name = "person_id"),
             inverseJoinColumns = @JoinColumn(name = "book_id"))
  @Sort(type = SortType.COMPARATOR, comparator = MyBookComparator.class)
  private SortedSet<BookEntity> books;
0 голосов
/ 06 января 2012

не уверен, правильно ли я понял вопрос, но если вы просто хотите заказать версию своего списка, вы можете просто отсортировать ее с помощью класса java.util.Collections и Comparator. Может быть, вы хотите сделать временный метод на вашем pojo, как это:

@Transient
public List<Book> getBooksASC()
{
    Collections.sort(this.books, new BookSorter.TitelASCSorter());
    return this.books;
}

Просто напишите класс, который реализует Comparator.

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