使用连接表存储库的@manytomany 中的 Spring 数据 jpa 规范和可分页
Posted
技术标签:
【中文标题】使用连接表存储库的@manytomany 中的 Spring 数据 jpa 规范和可分页【英文标题】:Spring data jpa specification and pageable in @manytomany using join table repository 【发布时间】:2020-07-26 18:36:49 【问题描述】:我有一个用例,使用单独的连接表对具有@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);
但是,当我们尝试基于规则/用户表属性(如 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 JoinTable 的存储库。
【问题讨论】:
【参考方案1】: @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;
【讨论】:
非常感谢@Kavithakaran 这个解决方案。你太棒了.. :) .以上是关于使用连接表存储库的@manytomany 中的 Spring 数据 jpa 规范和可分页的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate JPA 没有在 ManyToMany 关联上创建连接表
Hibernate中的ManyToMany映射引用错误(由api生成的表名)表Spring Boot