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

标签 java spring jpa spring-data spring-data-jpa

我尝试为某个实体实现过滤器。 据我所知,Spring不支持可选参数,因此当没有设置过滤器时,我会检查空字符串,当设置参数时,我想匹配包含不区分大小写

目前,没有任何产品链接到数据库中的角色,因此 p.role始终为空。 这意味着表达式的第二部分 ( 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尝试匹配 p.role.name 为 null结果出现错误,但没有错误消息,我也尝试包含 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);

关于java - Spring Data JPA 无法返回复杂表达式的正确结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42156619/

相关文章:

java - 在 mysql 中存储和检索 DSA 公钥和私钥

java - Spring NullPointerException 尽管使用了相关注释

spring - spring mvc中并发用户登录

spring - 为什么Springboot的JPA实体是抽象的?

java - 提高 JPA 初始化性能

java - 如何在java中深度复制对象。该对象可能是也可能不是可序列化的

java - JavaFX应用程序中的应用程序启动方法出现异常

java - 当我在 RoomDatabase 中使用 createFromAsset 时,为什么数据库为空。 List<> 的大小为 0,但预填充的数据库有 8 个项目

spring - 带有 Spring Boot 应用程序的 buildNumber 插件 Maven 不适用于 Tomcat

java - 修复了使用 JPA、Criteria API 和静态元模型时的列值