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;
}
我有一个用例,使用单独的联接 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;
}