Java 使用JPA 2.1标准API之间的LocalDate

Java 使用JPA 2.1标准API之间的LocalDate,java,jpa,jpa-2.1,jpa-criteria,Java,Jpa,Jpa 2.1,Jpa Criteria,在我的实体中,我有两个字段: private LocalDate startDate = LocalDate.of(1900, 1, 1); private LocalDate endDate = LocalDate.of(3000, 1, 1); 使用JPA标准API,我想选择LocalDate.now()>startDate和LocalDate.now()

在我的实体中,我有两个字段:

private LocalDate startDate = LocalDate.of(1900, 1, 1);
private LocalDate endDate = LocalDate.of(3000, 1, 1);
使用JPA标准API,我想选择
LocalDate.now()>startDate
LocalDate.now()
的实体

我尝试了以下方法:

predicates.add(builder.greaterThan(LocalDate.now(), path.<LocalDate> get(Entity_.startDate)));
predicates.add(builder.lessThan(builder.currentDate(), path.<LocalDate> get(Entity_.endDate)));
predicates.add(builder.greaterThan(LocalDate.now(),path.get(Entity.startDate));
add(builder.lessThan(builder.currentDate(),path.get(Entity.endDate));
但我得到了这个错误:

The method greaterThan(Expression<? extends Y>, Expression<? extends Y>) in the type CriteriaBuilder is not applicable for the arguments (LocalDate, Path<LocalDate>)

方法大于(表达式由于
jpa2.1
尚不直接支持
LocalDate
,因此您似乎需要一个
AttributeConverter
。假设您有一个
实体

@Entity
@Getter
public class LocalDateEntity {
   @Id
   @GeneratedValue
   private Long id;
   @Setter
   private LocalDate startDate = LocalDate.of(1900, 1, 1);
   @Setter
   private LocalDate endDate = LocalDate.of(3000, 1, 1);
}
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<LocalDateEntity> cq = cb.createQuery(LocalDateEntity.class);
Root<LocalDateEntity> from = cq.from(LocalDateEntity.class);
Expression<Date> expCurrDate = cb.currentDate();
cq.where(
      cb.and(
            cb.greaterThan(from.get("endDate"), expCurrDate)
            ,cb.lessThan(from.get("startDate"), expCurrDate)
           // OR for example
           // cb.lessThan(expCurrDate, from.get("endDate"))
           // ,cb.greaterThan(expCurrDate, from.get("startDate"))
           // both are expressions no matter in what order
           // but note the change in Predicate lt vs. gt
      )
);
TypedQuery<LocalDateEntity> tq = em.createQuery(cq);
您可以像这样使用
AttributeConverter

// import java.sql.Date not java.util.Date;
@Converter(autoApply = true) // this makes it to apply anywhere there is a need
public class LocalDateConverter implements AttributeConverter<LocalDate, Date> {

   @Override
   public Date convertToDatabaseColumn(LocalDate date) {
      return Date.valueOf(date);
   }

   @Override
   public LocalDate convertToEntityAttribute(Date value) {      
      return value.toLocalDate();
   }
}

注意:while Predicate
between(..)
也可以,但有点不同。它包括开始和结束日期。

不是100%确定,但您可能应该使用
大于(表达式)的方法
// import java.sql.Date not java.util.Date;
@Converter(autoApply = true) // this makes it to apply anywhere there is a need
public class LocalDateConverter implements AttributeConverter<LocalDate, Date> {

   @Override
   public Date convertToDatabaseColumn(LocalDate date) {
      return Date.valueOf(date);
   }

   @Override
   public LocalDate convertToEntityAttribute(Date value) {      
      return value.toLocalDate();
   }
}
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<LocalDateEntity> cq = cb.createQuery(LocalDateEntity.class);
Root<LocalDateEntity> from = cq.from(LocalDateEntity.class);
Expression<Date> expCurrDate = cb.currentDate();
cq.where(
      cb.and(
            cb.greaterThan(from.get("endDate"), expCurrDate)
            ,cb.lessThan(from.get("startDate"), expCurrDate)
           // OR for example
           // cb.lessThan(expCurrDate, from.get("endDate"))
           // ,cb.greaterThan(expCurrDate, from.get("startDate"))
           // both are expressions no matter in what order
           // but note the change in Predicate lt vs. gt
      )
);
TypedQuery<LocalDateEntity> tq = em.createQuery(cq);