Ehcache не работает в кластерном приложении

В моем приложении есть монолитное приложение, которое предоставляется Spring Ehcache. Оно работает правильно. Важно знать, что конфигурация кэша выполняется при сервисном методе, и отложенная загрузка выполняется для всех объектов, запрашиваемых из DB. Например:

@Transactional
@Override
@Caching(evict = { @CacheEvict(value = "schoolCache", key = "#school.id")})
public Integer save(School school) {
        // Code here
}

Ясно, что то, что сохраняется в Ehcache, является ленивым экземпляром школы. На уровне контроллера есть ModelMapper для обмена данными между Model и ViewModel следующим образом:

@RequestMapping(value = "/load/{Id}", method = RequestMethod.GET)
@ResponseBody
public SchoolViewModel load(@PathVariable Integer Id) {
        SchoolViewModel schoolViewModel = ModelMapper.map(schoolService.loadByEntityId(Id), SchoolViewModel.class);
        return schoolViewModel;
    }

Если SchoolViewModel имеет атрибут объекта, который находится в школе, выбирается из БД на контроллере с помощью ModelMapper. Поэтому я кластеризовал приложение и настроил Ehcache для Redis.
В чем проблема? В начале, когда запрос запроса от SchoolService, этот запрос службы из БД и, поскольку сеанс hibernate был открыт,ModelMapper успешно отображает Model в ViewModel. Во второй раз метод службы, который вызывается с идентификатором id, идентичным идентификатору сначала время получения школьного объекта от Redis, и нет сеанса Hiberante,ModelMapper, который хочет отобразить атрибут объекта, который находится в школе, получает исключение. Исключение выглядит так:

Вызвано: org.hibernate.LazyInitializationException: не удалось инициализировать прокси-сервер - нет сеанса в org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:165) в org.hibernate.proxy.AbstractLazyInitleizer.Lite.jpg). в org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)

Так как мне это сделать? Как мне лучше всего помочь? большое спасибо

1 ответ

Как я объяснил в моей книге, вам нужно инициализировать все ассоциации, которые вам понадобятся в методе обслуживания:

schoolService.loadByEntityId(Id), SchoolViewModel.class)

Итак, у вас есть несколько вариантов:

  1. Вы можете использовать JOIN FETCH с запросом JPQL.
  2. Ты можешь использовать Hibernate.initialize(proxy) или же Hibernate.unproxy(proxy),
  3. Вы можете просто перемещаться по ленивым ассоциациям.
  4. Вы можете использовать проекцию DTO, и вы никогда не столкнетесь с LazyInitializationException,
Другие вопросы по тегам