繁体   English   中英

Spring Data JPA无法使用复杂的表达式返回正确的结果

[英]Spring Data JPA fails to return correct result with complex expression

我尝试为某个实体实施过滤器。 据我所知,Spring不支持可选参数,因此当未设置过滤器时,我会检查空字符串,而在设置参数时,我要匹配包含且不区分大小写的内容

当前,没有产品链接到数据库中的角色,因此p.role始终为null。 这意味着表达式的第二部分lower(p.role.name) like concat('%', lower(:role), '%') )永远不会为真,从而导致一个空集。 但是第一部分( :role = '' )应该是正确的,因此我希望可以获取所有数据。 但是由于某种原因,它在这种情况下不起作用。

ProductRepository.java

@RepositoryRestResource(collectionResourceRel = "product", path = "/product")
public interface ProductRepository extends JpaRepository<Product, Long> {
    @RestResource(path="filter", rel="filter")
    @Query("select p from Product p where"
        + "(:vendor = '' or lower(p.vendor.name) like concat('%', lower(:vendor), '%'))"
        + "and"
        + "(:role = '' or lower(p.role.name) like concat('%', lower(:role), '%'))"
    Page<Product> filterProduct(@Param("role") String role, Pageable pageable);
}

Product.java

@Entity
public class Product {
    @ManyToOne
    @JoinColumn(name = "role_id", referencedColumnName = "id")
    private Role role;

    @ManyToOne
    @JoinColumn(name = "vendor_id", referencedColumnName = "id")
    private Vendor vendor;
}

Role.java

@Entity
public class Role {
    private Long id;
    private String name;
}

Vendor.java

@Entity
public class Vendor {
    private Long id;
    private String name;

我的测试

为了进行测试,我用始终为true或false( 1=11=2 )的语句替换了表达式的第二部分。

ProductRepository.java

@RepositoryRestResource(collectionResourceRel = "product", path = "/product")
public interface ProductRepository extends JpaRepository<Product, Long> {
    @RestResource(path="filter", rel="filter")
    @Query("select p from Product p where"
        + "(:role = '' or 1=2)"
    Page<Product> filterProduct(@Param("role") String role, Pageable pageable);
}

情况1=1

我是否提供role参数都没关系,我总是得到所有产品。

情况1=2

如果我不提供role参数(例如http://localhost/product/search/filter?role= ),则会得到所有产品,因为:role = ''评估为true

如果我确实提供了role参数(例如http://localhost/product/search/filter?role=foo ),则会得到一个空集,因为不存在名称为'foo'的角色。

我认为这可能是因为p.role为null试图匹配p.role.name导致错误,但是没有错误消息,而且我还尝试在表达式中包含p.role is not null and ...而是没变。

总结

  • :role = ''仅能按预期工作。
  • :role = ''与简单的表达式结合使用。
  • :role = ''结合我想工作的表达。

您不能使用点表示法直接访问关联的实体列。 用别名声明连接以访问:

@RestResource(path="filter", rel="filter")
@Query("select p from Product p LEFT JOIN p.role r LEFT JOIN p.vendor v where"
    + "(:vendor = '' or lower(v.name) like concat('%', lower(:vendor), '%'))"
    + "and"
    + "(:role = '' or lower(r.name) like concat('%', lower(:role), '%'))")
Page<Product> filterProduct(@Param("vendor") String vendor, @Param("role") String role);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM