2012-05-24 3 views
4

У меня есть объект пользователя в моих приложениях набор моделей, определяются следующим образом:LazyInitializationException при использовании ElementCollection в рамках Play

public class User extends Model { 

    private String name; 

    private byte[] sk; 

    @Column(columnDefinition = "BINARY(272)") 
    private byte[] pk; 

    private int port; 

    @OneToOne 
    public Profile profile; 

    @ElementCollection 
    public List<String> friends; 

    @ElementCollection 
     public List<String> mirrors; 
... 
} 

и в способе в другой части моего приложения (класс контроллера) Я извлечения и попытки изменить список зеркал следующим образом:

User u = User.connect(username); 
    int port = ProfileFinder.getLocation(username, mirror); 
    u.mirrors.remove(mirror); 
    u.save(); 

Это бросает ошибку о том, что:

LazyInitializationException occured : failed to lazily initialize a collection of role: models.User.mirrors, no session or session was closed 

Я подозреваю, что это связано с неправильным пониманием какого-либо элемента тега @ElementCollection, но может ли кто-нибудь уточнить, как я мог это исправить?

Спасибо.

ответ

7

По умолчанию XxxToMany ассоциации и коллекции элементов загружаются лениво.

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

Либо вы его загрузите, установив атрибут fetch аннотации, либо вы используете запрос или службу, которые инициализируют коллекцию в транзакции, прежде чем возвращать ее. Помните, что если вы его загрузите, он ВСЕГДА будет загружен, даже если вам не нужны элементы коллекции.

0

Да, вы должны использовать аннотацию EAGER, но будьте осторожны, потому что, как говорит JB Nizet, эти элементы будут всегда загружаться.

0

Если вы не хотите менять ленивую нагрузку на желающих, у вас есть еще один вариант: слияние.

User u = User.connect(username); 
u.merge(); 

Merge возьмет объект, который отключен от сеанса и снова подключит его.

Например, если вы кешируете объект (в данном случае экземпляр пользователя), вы не можете получить зеркала объектов пользователя, не используя при этом .merge().

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