Spring data jpa specification and pageable in @manytomany using join table 存储库

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

我有一个用例,使用单独的联接 table 过滤和分页具有 @manytomany 关系的记录。 下面是关系和实体

   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);

但是当我们尝试基于 Rule/User table 属性(例如 userName/roleName specBuilder.with("user.userName", "eq" , "xyz"); 进行过滤时,出现以下异常:

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

如果有任何方法可以使用 UserRole Join Table 存储库和规范来实现过滤器,请提出建议

分页也是必需的,因此使用 UserRole Join 类型的存储库Table。

    @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;
    }