2013-07-15 3 views
1

Ниже приведен код ошибки Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.model.entity.WorkflowProcessEntity.workstations, no session or session was closed. Таким образом, я завернул метод с @Transactional в классе обслуживания, и он по-прежнему вызывает ошибку.не удалось лениво инициализировать коллекцию, когда внутри транзакции

WorkstationService workstationService = (WorkstationService) ApplicationContextProvider.getApplicationContext().getBean("workstationService"); 
    for (WorkstationEntity workstationEntity : workstationService.getWorkstations(getEntity())) { 
     registerWorkstation(new ImpositionWorkstation(workstationEntity)); 
    } 

WorkstationService.java

@Transactional(readOnly = true) 
public Collection<WorkstationEntity> getWorkstations(WorkflowProcessEntity workflowProcessEntity) { 
    return workflowProcessEntity.getWorkstations(); 
} 

WorkflowProcessEntity.java

@OneToMany(mappedBy = "workflowProcess") 
@JsonIgnore 
public Collection<WorkstationEntity> getWorkstations() { 
    return workstations; 
} 

Как я могу запросить эти отношения правильно?

+0

Опубликовать полную трассировку стека исключения и соответствующий код. –

+0

Релевантный код выше ... он пытается загрузить отношения getWorkstations(). – Webnet

+1

И трассировка стека? –

ответ

5

У вас есть две проблемы в коде.

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

Во-вторых, вы предполагаете, что получение коллекции для объекта загружает его. Это тоже не так. Коллекция реализована как ленивый прокси-сервер, и получение коллекции и возврат ее не что иное, как получение прокси-сервера (unitilialized) и возврат его. Только при вызове метода в коллекции прокси-сервер инициализирует себя. Например, при итерации по коллекции. И это делается за пределами транзакции. Трассировка стека, если бы вы предоставили ее, вероятно, подтвердила бы, что исключение io не выбрано изнутри службы, а из итерации вне службы.

+0

Не могли бы вы рассказать о том, что делает сущность удаленной? – Webnet

+0

Как только сеанс, который загрузил объект, закрыт (что в типичном приложении Spring происходит, когда транзакция завершается, если у вас нет фильтра с открытым окном), объект становится отсоединенным. –

+0

Спасибо за отзыв ... вы правы в трассировке стека. Хотя я не совсем ясно, как структурировать мой код для решения проблемы. Является ли распространенным в Spring/Java-приложениях восстановление объекта при необходимости запроса его отношений? – Webnet

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