2

我有以下查询:

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)

缓存可以正常工作。

原因是什么?

编辑

类定义:

@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;
    
    ...

我正在使用休眠 5.3.12.Final

4

1 回答 1

2
  • 我不认为您正在重用缓存的查询,因为您new Date()在标准构建器中使用,因此parameter绑定到查询的结果每次都不同。
   criteriaBuilder.between(criteriaBuilder.literal(new Date())...
  • 出于测试目的,修改findArticlesById方法 findArticlesById(String id, Date date)并将其传递date给两个调用并查看
于 2020-07-10T10:16:50.430 回答