spring-boot / spring-data-jpa自定义查询过滤按日期字段返回结果而不过滤

时间:2017-05-18 13:05:36

标签: postgresql jpa spring-boot spring-data-jpa

我正在使用spring-boot-starter-data-jpa-1.5.2.RELEASE开发一个spring-boot REST服务器。我有以下POJO类层次结构。首先是基类Entity:

@javax.persistence.Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Entity implements Serializable {    

    @Id
    @Column(name = "id", nullable = false, length = 48)
    public String id = UNINITIALIZED_ID;

    /**
     * The timestamp for when this entity was last updated.
     */
    @Column(columnDefinition = "timestamp with time zone")
    @Temporal(TemporalType.TIMESTAMP)
    public Date updateTimestamp = new Date();

}

接下来是具体的子类患者:

@javax.persistence.Entity
@Table(indexes={@Index(columnList="updateTimestamp")})
public class Patient extends Entity {
...
}

我使用自定义方法定义我的PatientRepository接口,以获取updateTimestamp在指定时间戳之后的患者:

@RepositoryRestResource(collectionResourceRel = "patients", path = "patients")
public interface PatientRepository extends JpaRepository<Patient, String> {
    List<Patient> findByUpdateTimestampAfter(@DateTimeFormat(iso=DateTimeFormat.ISO.DATE_TIME)@Param("after")Date after);
}

由于某些未知原因,当我通过Advanced Rest Client Chrome插件发出以下GET请求时,updateTimestamnp过滤器无效:

// url example. DateFormat matches @DateTimeFormat on param in query method. 
GET http://127.0.0.1:8090/patients?after=2030-01-10T00:00:00.000-05:00

我希望只返回那些在指定时间戳之后有updateTimestamp的实体,但我得到的却是资源集合中的所有实体。

我在spring-boot上启用了DEBUG日志记录。以下是我不确定的问题:

2017-05-18 10:15:56.127 DEBUG 5292 --- [           main] o.s.d.j.r.query.JpaQueryFactory          : Looking up query for method findByUpdateTimestampAfter
2017-05-18 10:15:56.132 DEBUG 5292 --- [           main] o.s.d.jpa.repository.query.NamedQuery    : Looking up named query Patient.findByUpdateTimestampAfter
2017-05-18 10:15:56.133 DEBUG 5292 --- [           main] o.s.d.jpa.repository.query.NamedQuery    : Did not find named query Patient.findByUpdateTimestampAfter

根据@pvpkiran的好建议,我对以下Spock集成测试进行了测试,并显示在调试Date后解析I PatientRepository.findByUpdateTimestampAfter方法按预期工作:

    @SpringBootTest(classes = com.altran.medmap.server.Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    @Transactional

class PatientRepositorySpec extends Specification {


    @Autowired
    PatientRepository patientRepository;


    @Bean
    @Unroll    
    def 'Should GET #size patients whose updateTimestamp is after: #after'( {
        given:
            DateFormat dateFormat = new SimpleDateFormat('MMM d, yyyy h:mm:ss a');
            Date afterx = dateFormat.parse(after);
        when:
            List<Patient> result = patientRepository.findByUpdateTimestampAfter(after);
        then:
          result.size() == size;
        where: 'result size matches expected'
            after                        | size
            'Jan 1, 2016 00:00:00 AM'    | 2
            'Jan 1, 2030 00:00:00 AM'    | 0

    }            
}

REST API仍在返回所有实体的事实仍然是一个未解之谜。不是我在Repository接口中的查询方法参数上指定了@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)并在rest URL中使用相同的格式。有什么建议从哪里开始?

1 个答案:

答案 0 :(得分:0)

我终于找到了导致其余界面没有提供过滤结果的愚蠢错误。我的网址路径不正确。

//Incorrect URL
http://127.0.0.1:8090/patients?after=2030-01-10T00:00:00.000-05:00

//Correct URL based on spring-data-rest default conventions
http://127.0.0.1:8090/patients/search/findByUpdateTimestampAfter?after=2030-01-10T00:00:00.000-05:00

请注意,在修复URL后,我收到了日期解析错误。我为here创建了一个新问题。

感谢@pvpkiran和@Afridi的帮助。