简体   繁体   English

Spring 数据 jpa 规范和可在 @manytomany 中使用连接表存储库进行分页

[英]Spring data jpa specification and pageable in @manytomany using join table repository

I have a use case to filter and paginate the record with @manytomany relation using a separate join table.我有一个用例使用单独的连接表使用@manytomany关系对记录进行过滤和分页。 Below are the relation and entities下面是关系和实体

   public class User {
        private Long userId;
        private String userName
        @OneToMany(mappedBy = "user")
        private List<UserRole> userRole;
    }
public class Role {
    private Long roleId;
    private String roleName
    @OneToMany(mappedBy = "role")
    private List<UserRole> userRole;
}

public class UserRole{
    private Long id;
    private Integer active
    @ManyToOne   
    @MapsId("userId")
    private User user;
    @ManyToOne   
    @MapsId("roleId")
    private Role role;
}
    @Repository
    public interface UserRoleRepository extends 
                       JpaRepository<UserRole, String>, 
                       JpaSpecificationExecutor<UserRole> {
    }
     public class UserRoleSpecification implements Specification<UserRole> 
     {
    
        private SearchCriteria criteria;
        
        public RuleEntitySpecification(SearchCriteria criteria ) {
            this.criteria = criteria;
        }
    
        @Override
        public Predicate toPredicate(Root<UserRole> root, 
                               CriteriaQuery<?> query,
                               CriteriaBuilder criteriaBuilder) {
            
          if(criteria.getOperation().equalsIgnoreCase("eq")) {
             if(root.get(criteria.getKey()).getJavaType() == String.class) 
             {
               return criteriaBuilder.like(root.get(criteria.getKey()), 
                                      "%" + criteria.getValue() + "%");
             } else {
               return criteriaBuilder.equal(root.get(criteria.getKey()), 
                                            criteria.getValue());
             }
           }
           return null;
        }
    
    }
    public class SearchCriteria implements Serializable {
    
        private String key;
        private String operation;
        private Object value;
    }
    UserRoleSpecificationBuilder specBuilder = new UserRoleSpecificationBuilder();
    
    specBuilder.with("active", "eq" , 1); // giving us proper result
    
    Specification<UserRole> spec = specBuilder.build();
    
    Pageable paging = PageRequest.of(0, 5, Sort.by("user.userId"));
    
    Page<UserRole> pagedResult = userRoleRepository.findAll(spec,paging);

But when we try to filter based on Rule/User table properties like userName/roleName specBuilder.with("user.userName", "eq", "xyz");但是,当我们尝试基于规则/用户表属性(如 userName/roleName)进行过滤时specBuilder.with("user.userName", "eq", "xyz"); , I am getting following exception: ,我收到以下异常:

    org.springframework.dao.InvalidDataAccessApiUsageException: 
    Unable to locate Attribute  with the the given name 
    [user.userName] on this ManagedType

Kindly suggest if there is any way to achieve the filter using UserRole Join Table repository and specification请建议是否有任何方法可以使用 UserRole Join Table 存储库和规范来实现过滤器

Pagination is also required hence using repository of Type UserRole JoinTable.因此也需要分页,因此使用类型 UserRole JoinTable 的存储库。

    @Override
    public Predicate toPredicate(Root<UserRole> root,
                                 CriteriaQuery<?> query,
                                 CriteriaBuilder criteriaBuilder) {
      if (criteria.getOperation().equalsIgnoreCase("eq")) {
         String key = criteria.getKey();
         Path path;
         if (key.contains(".")) {
            String attributeName1 = key.split("\\.")[0];
            String attributeName2 = key.split("\\.")[1];
            path = root.get(attributeName1).get(attributeName2);
         } else {
            path = root.get(key);
         }
         if (path.getJavaType() == String.class) {
           return criteriaBuilder.like(path, "%" + criteria.getValue() + "%");
         } else {
           return criteriaBuilder.equal(root.get(key), criteria.getValue());
         }
      }
      return null;
    }

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

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