当条件暗示日期时,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 传递给两个调用并查看