如何在Spring Data JPA的@Query中比较实体属性而非ID?
解决Spring Data JPA @Query中比较实体非主键属性的问题
你遇到的问题很典型:当在JPQL中直接用实体对象(比如a.state = :state)进行比较时,JPA默认会使用该实体的主键字段(通常是id)来做匹配,这就是为什么实际执行时是比较state的id。要比较state的其他属性,你需要明确指定要匹配的字段,而不是直接用实体对象做整体比较。
下面给你两种可行的解决方案,结合你的原有查询语句来修改:
方案1:直接传入目标属性的值,在JPQL中指定对应字段
如果你的方法参数是state的某个属性值(比如state的status字段值),可以把查询语句里的a.state = :state替换为a.state.status = :stateStatus,示例如下:
@Query("select a from ApplyOfIP as a left join a.state " + "where a.state.status = :stateStatus " + "and a.applicant.department like %:department% " + "and (a.finallyIPName like %:ipName% or a.applyInfo.applyIPName like %:ipName%) " + "and a.applicant.name like %:applicantName%") Page<ApplyOfIP> findByStateStatusAndConditions( @Param("stateStatus") String stateStatus, @Param("department") String department, @Param("ipName") String ipName, @Param("applicantName") String applicantName, Pageable pageable );
这样JPA就会用传入的stateStatus值去匹配state实体的status字段,而不是主键id。
方案2:传入完整的State实体,指定其属性进行匹配
如果你还是想在方法参数中传入完整的State实体对象,那么可以在JPQL中明确引用该实体的目标属性,比如a.state.status = :state.status,示例如下:
@Query("select a from ApplyOfIP as a left join a.state " + "where a.state.status = :state.status " + "and a.applicant.department like %:department% " + "and (a.finallyIPName like %:ipName% or a.applyInfo.applyIPName like %:ipName%) " + "and a.applicant.name like %:applicantName%") Page<ApplyOfIP> findByStateAndConditions( @Param("state") State state, @Param("department") String department, @Param("ipName") String ipName, @Param("applicantName") String applicantName, Pageable pageable );
这里需要注意:确保传入的State实体中status属性已经被正确赋值,JPA会提取这个属性的值来进行匹配。
另外补充一点:你的查询中使用了left join a.state,其实在JPQL中如果只是引用a.state的属性,这个join是可以省略的,JPA会自动处理关联查询,不过保留也没问题。
内容的提问来源于stack exchange,提问作者ban jue
相关产品推荐
相关产品推荐

