Исключение отложенной инициализации Hibernate для загрузки ленивого списка - PullRequest
0 голосов
/ 20 июня 2020

У меня есть эти две сущности

@Entity
@Table(name = "CallSession")
public class CallSession implements Serializable {

    private long id;
    private List<CallParticipant> members;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public long getId() {
        return id;
    }

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

    @OneToMany(mappedBy = "callSession", fetch = FetchType.LAZY)
    public List<CallParticipant> getMembers() {
        return members;
    }

    public void setMembers(List<CallParticipant> members) {
        this.members = members;
    }    
}    


@Entity
@Table(name = "CallParticipant")
public class CallParticipant implements Serializable {    

    private long id;
    private CallSession callSession;    

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public long getId() {
        return id;
    }

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

    @ManyToOne
    public CallSession getCallSession() {
        return callSession;
    }

    public void setCallSession(CallSession callSession) {
        this.callSession = callSession;
    }    
}

, но когда я вызываю метод callSession.getMembers(), я получаю следующее исключение:

Невозможно оценить выражение, выброшенное методом 'org. hibernate.LazyInitializationException 'исключение.

Я не могу понять, почему я получаю эту ошибку? Почему я получаю эту ошибку и как ее исправить?

1 Ответ

0 голосов
/ 20 июня 2020

Я собираюсь начать с предположения, что вы хотите, чтобы ваша коллекция была загружена лениво.

Сеанс Hibernate может быть закрыт во многих контекстах, и как только сеанс будет закрыт, он не сможет получить какие-либо ленивые загруженные коллекции.

Обычно Hibernate очень хорош для поддержания открытых сессий для жизненного цикла HTTP-потоков в контексте веб-приложения («открытый сеанс в поле зрения» Spring). Причины, по которым сеанс может быть закрыт, включают то, что объект был передан из одного потока в другой, или объект был кэширован, а затем был доступен другому потоку.

Но это может быть сложнее, если ваш код выполняется в задание или контекст не веб-приложения.

Исправления

1. Создайте метод репозитория для явного получения коллекции

Используя @Query и join fetch, добавьте метод репозитория, который явно загружает коллекцию с нетерпением.

2. Вызовите .toString () для коллекции после получения объекта.

Это неприятный прием, который я видел раньше, многие люди использовали в реальном мире. По сути, перед кешированием объекта или передачей его исполнителю или где-то там, где к нему будет обращаться другой поток, вызовите .toString () в коллекции, чтобы загрузить его. Обычно оставляют комментарий, объясняющий почему.

3. Добавьте @Transactional к методу, который одновременно получает данные и обращается к коллекции. исправление для сохранения активности сеанса, например, в методе задания.

Надеюсь, это поможет.

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