当条件暗示日期时,Hibernate 查询缓存不起作用
Hibernate query cache doesn't work when criteria implies date
我有以下查询:
public List<SomeEntity> findArticlesById(String id) {
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
final CriteriaQuery<SomeEntity> criteriaQuery = criteriaBuilder.createQuery(SomeEntity.class);
final Root<SomeEntity> root = criteriaQuery.from(SomeEntity.class);
final Join<SomeEntity, SomeOtherEntity> join = root.join(SomeEntity.property);
criteriaQuery
.select(root)
.where(
criteriaBuilder.equal(join.get(SomeEntity_.id), id),
criteriaBuilder.between(criteriaBuilder.literal(new Date()), join.get(SomeEntity_.startDate), join.get(SomeEntity_.endDate))
);
return entityManager.createQuery(criteriaQuery)
.setHint(QueryHints.HINT_CACHEABLE, true)
.setHint(QueryHints.HINT_CACHE_REGION, CacheRegions.QUERY_ENTITY)
.getResultList();
}
我希望在我调用两次时命中查询缓存,但它不起作用。
但是,如果我删除第二个谓词
criteriaBuilder.between(criteriaBuilder.literal(new Date()), join.get(SomeEntity_.startDate), join.get(SomeEntity_.endDate)
缓存正常工作。
是什么原因?
编辑
class定义:
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@Entity
@Table(name = "SOME_ENTITY")
public class SomeEntity implements Serializable {
@EmbeddedId
private SomeEntityPk pk;
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@LazyToOne(LazyToOneOption.NO_PROXY)
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="ID", referencedColumnName="ID", insertable = false, updatable = false)
private SomeOtherEntity someOtherEntity;
...
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@Entity
@Table(name = "SOME_ENTITY")
public class SomeEntity implements Serializable {
@EmbeddedId
private SomeEntityPk pk;
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@LazyToOne(LazyToOneOption.NO_PROXY)
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="ID", referencedColumnName="ID", insertable = false, updatable = false)
private SomeOtherEntity someOtherEntity;
...
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@Entity
@Table(name="SOME_OTHER_ENTITY")
public class SomeOtherEntity implements Serializable {
@Id
@Column(name="ID")
private String id;
@Column(name="DATE_START")
@Temporal(TemporalType.TIMESTAMP)
private Date startDate;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="DATE_END")
private Date endDate;
@LazyToOne(LazyToOneOption.NO_PROXY)
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@OneToMany(fetch=FetchType.LAZY, mappedBy=SomeEntity_.SOMEOTHERENTITY)
private List<SomeEntity> someEntities;
...
我正在使用 Hibernate 5.3。12.Final
- 我不认为您正在重用缓存的查询,因为您在条件生成器中使用
new Date()
,因此绑定到查询的 parameter
每次都不一样。
criteriaBuilder.between(criteriaBuilder.literal(new Date())...
- 出于测试目的,将
findArticlesById
方法修改为 findArticlesById(String id, Date date)
并将相同的 date
传递给两个调用并查看
我有以下查询:
public List<SomeEntity> findArticlesById(String id) {
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
final CriteriaQuery<SomeEntity> criteriaQuery = criteriaBuilder.createQuery(SomeEntity.class);
final Root<SomeEntity> root = criteriaQuery.from(SomeEntity.class);
final Join<SomeEntity, SomeOtherEntity> join = root.join(SomeEntity.property);
criteriaQuery
.select(root)
.where(
criteriaBuilder.equal(join.get(SomeEntity_.id), id),
criteriaBuilder.between(criteriaBuilder.literal(new Date()), join.get(SomeEntity_.startDate), join.get(SomeEntity_.endDate))
);
return entityManager.createQuery(criteriaQuery)
.setHint(QueryHints.HINT_CACHEABLE, true)
.setHint(QueryHints.HINT_CACHE_REGION, CacheRegions.QUERY_ENTITY)
.getResultList();
}
我希望在我调用两次时命中查询缓存,但它不起作用。
但是,如果我删除第二个谓词
criteriaBuilder.between(criteriaBuilder.literal(new Date()), join.get(SomeEntity_.startDate), join.get(SomeEntity_.endDate)
缓存正常工作。
是什么原因?
编辑
class定义:
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@Entity
@Table(name = "SOME_ENTITY")
public class SomeEntity implements Serializable {
@EmbeddedId
private SomeEntityPk pk;
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@LazyToOne(LazyToOneOption.NO_PROXY)
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="ID", referencedColumnName="ID", insertable = false, updatable = false)
private SomeOtherEntity someOtherEntity;
...
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@Entity
@Table(name = "SOME_ENTITY")
public class SomeEntity implements Serializable {
@EmbeddedId
private SomeEntityPk pk;
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@LazyToOne(LazyToOneOption.NO_PROXY)
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="ID", referencedColumnName="ID", insertable = false, updatable = false)
private SomeOtherEntity someOtherEntity;
...
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@Entity
@Table(name="SOME_OTHER_ENTITY")
public class SomeOtherEntity implements Serializable {
@Id
@Column(name="ID")
private String id;
@Column(name="DATE_START")
@Temporal(TemporalType.TIMESTAMP)
private Date startDate;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="DATE_END")
private Date endDate;
@LazyToOne(LazyToOneOption.NO_PROXY)
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@OneToMany(fetch=FetchType.LAZY, mappedBy=SomeEntity_.SOMEOTHERENTITY)
private List<SomeEntity> someEntities;
...
我正在使用 Hibernate 5.3。12.Final
- 我不认为您正在重用缓存的查询,因为您在条件生成器中使用
new Date()
,因此绑定到查询的parameter
每次都不一样。
criteriaBuilder.between(criteriaBuilder.literal(new Date())...
- 出于测试目的,将
findArticlesById
方法修改为findArticlesById(String id, Date date)
并将相同的date
传递给两个调用并查看