Кеш запросов гибернации не работает, когда критерии подразумевают дату - PullRequest
2 голосов
/ 09 июля 2020

У меня есть следующий запрос:

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();
}

Я бы ожидал, что кеш запроса будет поражен, когда я вызываю дважды, но это не работает.

Однако, если я удалить 2-й предикат

criteriaBuilder.between(criteriaBuilder.literal(new Date()), join.get(SomeEntity_.startDate), join.get(SomeEntity_.endDate)

кеш вместо этого работает правильно.

В чем причина?

EDIT

определение класса:

@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

1 Ответ

2 голосов
/ 10 июля 2020
  • Я не думаю, что вы повторно используете кэшированный запрос, потому что вы используете new Date() в построителе критериев, и в результате parameter s, привязанные к запросу, каждый раз различаются.
   criteriaBuilder.between(criteriaBuilder.literal(new Date())...
  • В целях тестирования измените метод findArticlesById на findArticlesById(String id, Date date) и передайте одно и то же date обоим вызовам и посмотрите
...