Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> hibernateTemplate. Pagination. 
V
    Опции темы
garbuz
Дата 30.7.2009, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Возникли непонятки с pagination.
Делаю так
Код

 public List<Post> getAll() {
        return template.findByExample(new Post(), 4 , 4);
    }

Выбираются четыре записи, причем выборка начинается не с четвертой, а с третье. И первые три выбранные записи одинаковые.
Делаю по-другому.
Код

public List<Post> getAll() {
        System.out.println("PostDAOImpl => getAll");
         DetachedCriteria criteria = DetachedCriteria.forClass(Post.class)
                .addOrder(Order.desc("createdDate"));
         return template.findByCriteria(criteria, 4, 4);
      
    }

Выбирается четыре записи, только по две одинаковых. Добавив эту строчку
Код

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

получаем две записи. Что же в итоге делать? Неужели чтобы получить 4 записи надо так писать?
Код

 public List<Post> getAll() {
        System.out.println("PostDAOImpl => getAll");
        //return template.find("FROM Post order by createdDate desc");


        DetachedCriteria criteria = DetachedCriteria.forClass(Post.class)
                .addOrder(Order.desc("createdDate"));
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        return template.findByCriteria(criteria, 4, 8);

    }

PM MAIL   Вверх
MisterCleric
Дата 30.7.2009, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 33
Всего: 38



Привет. Нет-нет. У тебя проблема связана с тем, что ты выбираешь коллекцию, элементы которой также содержат коллекции. Т.е. твой Post содержит ManyToOne List<Message>.
в результате используется InnerJoin в селекте. а подумай сам: когда ты такой запрос выполнишь на базе, сколько раз у тебя повторится инфа по посту? Да столько сколько мессаждей в этом посте.

Что бы такого не происходило, надо или LazyLoad(а может и не поможет...) или вот так:
Код

@Entity
@SequenceGenerator(name = "SEQUENCE", sequenceName = "GEN_TOPIC", allocationSize = 1)
@org.hibernate.annotations.AccessType("field")
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
public class Topic implements Serializable {
    @Id
    @GeneratedValue(generator = "SEQUENCE")
    @Column(updatable = false, nullable = false, unique = true)
    private Long id;

 @OneToMany(mappedBy = "topic", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @Fetch(FetchMode.SELECT) // сюда обратить внимание!!!
    @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
    @OrderBy("regDate desc")
    private List<Message> messages = new ArrayList<Message>();
}



--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
garbuz
Дата 30.7.2009, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



Цитата(MisterCleric @  30.7.2009,  10:55 Найти цитируемый пост)
Привет. Нет-нет. У тебя проблема связана с тем, что ты выбираешь коллекцию, элементы которой также содержат коллекции. Т.е. твой Post содержит ManyToOne List<Message>.

Вот класс
Код

@Entity
@Table(name="posts")
public class Post {
    
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="postId")
    private Long postId;
    
    @Column(name="title")
    private String postName;

    @Column(name="preview")
    private String preview;
    
    @Column(name="content")
    private String postBody;
    
    @ManyToOne(cascade = {CascadeType.REFRESH}, fetch = FetchType.EAGER)
    @JoinColumn(name="userId")
    private User author;
    
        
    @ManyToMany(cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
    @JoinTable(name="posts_tags",
    joinColumns = @JoinColumn(name = "postId"),
    inverseJoinColumns = @JoinColumn(name = "tagId"))
    private Set<Tag> tags;
    
    @ManyToOne(cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
    @JoinColumn(name="categoryId")
    private Category category;
    
    
    @ManyToOne(cascade = {CascadeType.REFRESH}, fetch = FetchType.EAGER)
    @JoinColumn(name="statusId")
    private Status status;

    @Column(name="createdDate")
    private Date createdDate;

    @Column(name="modifiedDate")
    private Date modifiedDate;

У всех полей FetchType.EAGER. Это наверно не очень хорошо, но пока так. У поста есть коллекция тегов и все. Пост имеется ввиду не тот что на форуме, а например тот что в блоге, который вместо сообщении содержит коментарии. В данном случае у поста нет коллекии комментариев. Каждый комментарий содержит ссылку на пост.
Посмотрел sql, котрый генерит хибернейт - это ужасно. Очень большой запрос со множеством джоинов. Джоины скорее всего из-за FetchType.EAGER

PM MAIL   Вверх
MisterCleric
Дата 30.7.2009, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 33
Всего: 38



Ну может я немного поспешил предугадать, но суть от этого не меняется:
из-за  того, что у тебя 
Цитата

private Set<Tag> tags;

и выходит вот это дублирование. поставь тот хинт, что я предложил и должно помочь.
У меня, собственно, так везде, где используется Pagination
Еще могу предложить такое архитектурное решение, для такой задачи, как вынос логики этой коллекции во VIEW на базе, или просто запросом, результат которого будет меппиться на твой Post, таким образом ты сможешь и логику свою обрабатывать и не будет у тебя лишних JOIN


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
garbuz
Дата 30.7.2009, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 677
Регистрация: 22.1.2008

Репутация: 8
Всего: 11



MisterCleric, спасибо! Вроде помогло! Дома вечерком еще попробую!

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0482 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.