如何构建Spring Data JPA查询方法名比较实体中的日期属性?
解决方案
Spring Data JPA的方法名查询语法不支持直接在方法名中定义实体属性之间的对比逻辑,你之前的写法会让框架误以为isAfterLastDeployed是modified属性的子属性,所以抛出找不到属性的错误。要实现你需要的查询,最直接的方式是使用@Query注解自定义JPQL语句:
方法1:使用@Query注解(推荐)
在你的仓库接口中添加以下方法:
import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; import java.util.stream.Stream; public interface ArtifactRepository extends CrudRepository<Artifact, Long> { @Query("SELECT a FROM Artifact a WHERE a.lastDeployed IS NULL OR a.lastDeployed < a.modified") Stream<Artifact> findByLastDeployedNullOrBeforeModified(); }
这个JPQL语句直接对应你的需求:筛选lastDeployed为null,或者lastDeployed早于modified的实例。
方法2:使用Criteria API(适合动态查询场景)
如果后续需要动态调整查询条件,可以用Specification来构建查询:
import org.springframework.data.jpa.domain.Specification; import javax.persistence.criteria.Predicate; import java.util.ArrayList; import java.util.List; public class ArtifactSpecifications { public static Specification<Artifact> lastDeployedNullOrBeforeModified() { return (root, query, criteriaBuilder) -> { List<Predicate> predicates = new ArrayList<>(); predicates.add(criteriaBuilder.isNull(root.get("lastDeployed"))); predicates.add(criteriaBuilder.lessThan(root.get("lastDeployed"), root.get("modified"))); return criteriaBuilder.or(predicates.toArray(new Predicate[0])); }; } }
然后在仓库中继承JpaSpecificationExecutor,并调用查询:
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import java.util.stream.Stream; public interface ArtifactRepository extends JpaRepository<Artifact, Long>, JpaSpecificationExecutor<Artifact> { // 直接使用Specification查询 default Stream<Artifact> findByLastDeployedNullOrBeforeModified() { return findAll(ArtifactSpecifications.lastDeployedNullOrBeforeModified(), Stream::stream); } }
总结:对于固定条件的查询,优先用@Query注解,代码更简洁直观;如果需要动态组合条件,再考虑Criteria API。
内容的提问来源于stack exchange,提问作者E-Riz
相关产品推荐
相关产品推荐

