使用@ManyToMany关系的Criteria API进行过滤

时间:2019-12-23 22:31:04

标签: java spring-data-jpa criteria-api

我有两个实体UserRole通过users_roles表连接。

@Data
@Entity
@NoArgsConstructor
@Table(name = "users")
@EqualsAndHashCode(exclude = "roles")
@ToString(exclude = "roles")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "username")
    private String username;

    @Column(name = "enabled")
    private boolean enabled;

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "users_roles",
            joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"))
    private List<Role> roles;
}

@Data
@Entity
@Table(name = "roles")
@ToString(exclude = "users")
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "role")
    private String role;

    @ManyToMany(mappedBy = "roles", fetch = FetchType.LAZY)
    private List<User> users;
}

我有一个基于条件API的过滤器:

@AllArgsConstructor
class UserSpecification implements Specification<User> {

    @NonNull
    private final UserFilter filter;

    @Override
    public Predicate toPredicate(@NotNull Root<User> root,
                                 @NotNull CriteriaQuery<?> query,
                                 @NotNull CriteriaBuilder builder) {
        Predicate predicate = builder.conjunction();
        List<Expression<Boolean>> expressions = predicate.getExpressions();
        filter.getId().ifPresent(id -> expressions.add(builder.equal(root.get("id"), id)));
        filter.getUsername().ifPresent(username -> expressions.add(builder.like(root.get("username"), username)));
        filter.isEnabled().ifPresent(isEnabled -> expressions.add(builder.equal(root.get("enabled"), isEnabled)));
        filter.getRoles().ifPresent(roles -> {
            expressions.add(builder.equal(root.get("roles"), roles)); // Problem here.
        });
        return predicate;
    }
}

所有过滤器都可以按角色正常工作。当我尝试使用builder.equal(root.get("roles"), roles)时出现错误:

  

java.lang.IllegalArgumentException:参数值[Role(id = 1,   role = ROLE_USER)]与预期的类型[java.util.Collection   (n / a)]

roles仍然是集合。这是怎么发生的?以及如何解决?

0 个答案:

没有答案