Hibernate кеш запросов LazyInitializationException - PullRequest
0 голосов
/ 08 июня 2018

У меня включен L2 и кеш запросов, и я сталкиваюсь со странной проблемой, когда у меня кешируется запрос.Все отношения в сущностях инициализируются ленивыми.Вот пример сущности, к которой я обращаюсь:

@Entity
@Cache(usage = READ_WRITE)
@Data
@NoArgsConstructor
@Accessors
@EqualsAndHashCode(of = "id", callSuper = false)
public class TestEntity {

  /** The Constant serialVersionUID. */
  private static final long serialVersionUID = 1L;

  @Id
  @Column(updatable = false)
  private Long id;

  @OneToOne(cascade = ALL, fetch = LAZY)
  private AnotherTestEntity anotherTestEntity;

}

@Entity
@Cache(usage = READ_WRITE)
@Data
@NoArgsConstructor
@Accessors
@EqualsAndHashCode(of = "id", callSuper = false)
public class AnotherTestEntity {

  /** The Constant serialVersionUID. */
  private static final long serialVersionUID = 1L;

  @Id
  @Column(updatable = false)
  private Long id;

  @Column
  private String property;

}

Когда я выполняю запрос, который не кэшируется:

@Transactional(readOnly = true)
public TestEntity findTestEntity() {
  TestEntity testEntity = testEntityRepository.findOne(1);
  testEntity.getAnotherTestEntity().getProperty(); 

  return testEntity;
}

При первом запуске этого метода он запрашивает базу данныхи добавляет объект в кэш L2.Во второй раз, когда я вызываю его, он загружает объект из кэша L2, и он все еще работает нормально.

Проблема возникает, когда я вызываю кешированный запрос.Вот пример:

@Repository
public interface TestEntityRepository {

  @Cachable(cacheNames = "testQuery")
  TestEntity findOne(Long id);
}

Я буду использовать тот же метод:

@Transactional(readOnly = true)
public TestEntity findTestEntity() {
  TestEntity testEntity = testEntityRepository.findOne(1);
  testEntity.getAnotherTestEntity().getProperty(); 

  return testEntity;
}

Когда я вызываю его в первый раз, он все еще работает, а точная загрузка данных из базы данных.Проблема возникает со вторым вызовом, когда он использует кеш запросов.Это исключение выдается, когда я получаю доступ к отложенному инициализированному отношению:

Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session

Я вижу, что сеанс отложенного инициализированного объекта является нулевым, но я не могу понять, почему это происходит.Поскольку мы знаем, что кеш запросов содержит только идентификаторы сущностей, связанных с этим запросом, он отправляется и извлекает их из L2 (ссылка: https://dzone.com/articles/pitfalls-hibernate-second-0).). Поэтому я не могу понять, почему первый пример (без кеша запросов)работает нормально, а второй ведет себя так странно. Может кто-нибудь объяснить и сказать мне, что я делаю неправильно?

Ответы [ 2 ]

0 голосов
/ 28 июня 2018

Так что я просто погрузился в эту проблему, и оказалось, что абстракция кеша Spring не может быть использована с прокси-сервером для отложенной загрузки в спящем режиме.Spring предоставляет вам абстракцию, и они не знают о спящем режиме и фундуке.Затем hazelcast обеспечивает их реализацию для работы с пружиной.Поэтому, когда метод, аннотированный @Cachable, называется Spring, аспект проверяет кэш (используя предоставленный CacheManager - в данном случае HazelcastCacheManager) и получает то, что находится в кэше.Проблема здесь в том, что сеанс в hibernate-прокси является временным (и это абсолютно нормально), поэтому мы извлекаем из кэша объект без сеанса hibernate и, поскольку spring не хочет связываться с hibernate, сеансне установлен.И тогда мы получаем LazyInitializationException.Но, в конце концов, это очень распространенная проблема, и странно, что к весне не существует решения.Работает только использование кеша запросов Hibernate, который имеет некоторые другие недостатки при использовании Hazelcast.

0 голосов
/ 08 июня 2018

Это может быть ошибка, но, конечно, вам нужно скопировать ее в соответствии с последней версией Hibernate ORM, используя этот шаблон теста .

Если вы не можете воспроизвести его, это означает, чтопроблема была либо исправлена, и вам нужно обновить Hibernate, либо проблема возникла в Spring, а не в Hibernate.

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