【发布时间】:2018-11-18 05:20:37
【问题描述】:
我启用了 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
我可以看到惰性初始化实体的会话为空,但我不知道为什么会这样。正如我们所知,查询缓存仅包含与该查询关联的实体的 ID,然后它会从 L2 中检索它们(参考:https://dzone.com/articles/pitfalls-hibernate-second-0)。所以我不明白为什么第一个例子(没有查询缓存)工作正常,而第二个例子表现得如此奇怪。有人可以解释并告诉我我做错了什么吗?
【问题讨论】:
标签: hibernate spring-boot spring-data