У меня следующий вопрос.Из того, что я понимаю, аннотация @Transactional
должна поддерживать сеанс, таким образом, позволяя лениво извлекать дочерние объекты без необходимости выполнения определенного запроса на присоединение.
У меня есть следующий сценарий, в котором я не понимаюпочему я все еще получаю LazyInitializationException
.
Мое приложение запускает распознаватель, чтобы обеспечить различные службы контроллера разрешенным объектом, чтобы его можно было использовать напрямую.
Указанный преобразовательперехватывает заголовок из запроса и, используя его значение, пытается запросить базу данных, чтобы получить объект.Теперь рассматриваемый объект довольно прост: он выполняет свои функции, хотя у него есть список из двух суб-сущностей.
Для выполнения действия разрешения я использую дополнительный сервис, в котором я в основном обертываю некоторую JpaRepository
методы.Полное описание приведено ниже:
@Service
public class AppClientServiceImpl implements AppClientService {
private static final Logger LOGGER = LoggerFactory.getLogger(AppClientServiceImpl.class.getCanonicalName());
private final AppClientRepository repository;
@Autowired
public AppClientServiceImpl(AppClientRepository repository) {
this.repository = repository;
}
@Override
@Transactional(readOnly = true)
public AppClient getByAppClientId(final String appClientId) {
LOGGER.debug("Attempting to retrieve appClient with id:: {}", appClientId);
return repository.findByAppClientId(appClientId);
}
@Override
@Transactional
public void saveAndFlush(final AppClient appClient) {
LOGGER.debug("Attempting to save/update appClient:: {}", appClient);
repository.saveAndFlush(appClient);
}
}
Как вы можете видеть, оба метода аннотированы как @Transactional
, что означает, что они должны поддерживать сеанс в контексте этого указанного метода.
Теперь,мои основные вопросы следующие:
1) Использование отладчика, который я вижу даже на этом уровне getByAppClientId
, список, содержащий на ленивых загруженных объектах, был решен просто отлично.
2) На самом распознавателе, где объект был получен от метода делегирования, список не может быть оценен из-за LazyInitializationException
.
3) Наконец, в конечном методе обслуживания контроллера, которыйтакже помечен как @Transactional
, то же самое, что и выше, означает, что в конечном итоге это не сработает (так как он выполняет получение списка, который не удалось инициализировать.
На основании всего вышеизложенного, я быХотелось бы знать, что является лучшим подходом при обработке этого. На этот раз я не хочу использовать тип извлечения Eager, и я также хотел бы избежать использования запросов извлечения. Также отмечая mПри разрешении на @Transactional
, таким образом, сохранение сеанса также не может быть и речи.
Я думал, что, поскольку @Transactional
оставит сеанс открытым, что позволит конечному методу обслуживания получитьсписок подразделенийПохоже, что это не так.
Исходя из всего вышесказанного, мне кажется, что мне нужен способ для окончательного метода обслуживания, который получает вызов (которому нужен список под рукой), чтобы каким-то образом получить его.
Какой лучший способ справиться с этим?Я прочитал довольно много постов здесь, но я не могу разобрать, какие методы являются наиболее приемлемыми для Spring boot 2.0 и hibernate 5.
Обновление:
Кажется, что комментирует подпрограмму.предоставьте следующие права:
@ Fetch (FetchMode.SELECT) @LazyCollection (LazyCollectionOption.TRUE)
Решает проблему, но я до сих пор не знаю, является ли это лучшим подходом.