2013-05-15 3 views
4

я Sessions и Users классов со следующими bi-directionalOneToMany отображения (генерируюсь с обратным проектированием Hibernate инструмента):Hibernate OneToMany двунаправленная связь медленно

public class Users { 
    @OneToMany(fetch=FetchType.LAZY, mappedBy="users") 
    public Set<Sessions> getSessionses() { 
     return this.sessionses; 
    } 
} 

public class Sessions { 
    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="USER_ID") 
    public Users getUsers() { 
     return this.users; 
    } 
} 

И вот мой код, который создает новую сессию для пользователя:

Session s = ...; 
Users user = (Users) s.createCriteria(Users.class) 
      ./*restrictions...*/.uniqueResult(); 
Sessions userSession = new Sessions(); 
userSession.setUsers(user); 
s.save(userSession); 
user.getSessionses().add(userSession); // here getSessionses() has 2k records 

У пользователя есть 2k сеансов, поэтому последняя строка очень медленная.

Как я могу связать сеанс с пользователем, не получая целую коллекцию сессий?

+0

Как вы загружаете объект 'user'? –

+1

Вам действительно нужна коллекция? Когда вы добавляете в него элемент, hibernate необходимо загрузить элементы для проверки дубликатов – Guillaume

+0

@Guillaume Set скорее является структурой данных мандата, навязанной Hibernate, чтобы сохранить уникальность. – sanbhat

ответ

3

Посмотрите на функцию extra-lazy loading Hibernate. Включите это, аннотируя свою коллекцию с помощью @LazyCollection(LazyCollectionOption.EXTRA). Существует this example, чтобы посмотреть, и есть Set, используемый в this one.

public class Users { 
    @OneToMany(fetch=FetchType.LAZY, mappedBy="users") 
    @LazyCollection(LazyCollectionOption.EXTRA) 
    public Set<Sessions> getSessionses() { 
     return this.sessionses; 
    } 
} 
+0

Отлично, спасибо! Он работает отлично. В этом случае hibernate генерирует только один запрос: 'SELECT 1 FROM SESSIONS WHERE USER_ID =? и SESSION_ID =? '. Это единственное решение, которое помогает исправить проблему, не меняя Set на список . –

1

Я не уверен, если спящий режим будет добавить соединение в обоих направлениях, но вместо добавления Session к User установить User в виде Session. Таким образом, вам не нужно загружать каждый сеанс.

+0

Hibernate [doc] (http://docs.jboss.org/hibernate/core/3.3/reference/en/html/tutorial.html#tutorial-associations-usingbidir) говорит, что: '' установка ссылки с обеих сторон '' абсолютно необходимо с двунаправленными ссылками ». Поэтому требуется установить ссылку с обеих сторон. –

+0

Можете ли вы опровергнуть мои комментарии ссылкой на официальную документацию? –

Смежные вопросы