如何使用Spring Data JPA过滤OneToMany字段?

时间:2019-05-26 09:23:21

标签: jpa spring-data-jpa spring-data one-to-many

我正在尝试根据是否将其设置为隐藏来过滤掉与某个类别关联的帖子。

我可以使用后查询过滤器很好地做到这一点(见下文),但是我想知道是否可以使用JPA方法构造查询? (特别是查询构建方法,例如FindAllBy ...,我希望通过坚持使用这些类型的查询来保持数据库不可知)

我还可能在PostRepository上调用FindAllByCategory并以这种方式构造返回值,但它感觉很棘手和倒退。

因此,总而言之,我想找到一种方法来声明FindAllAndFilterPostsByIsHidden(boolean isHidden)

类别分类

@Entity
public class Category {

    public Category(String name, Post... posts) {
        this.name = name;
        this.posts = Stream.of(posts)
            .collect(Collectors.toSet());
        this.posts.forEach(post -> post.setCategory(this));
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    private String name;

    @OneToMany(mappedBy = "category")
    private Set<Post> posts;
}

岗位班级(为了简洁起见,已精简为基础)

@Entity
public class Post {

    public Post(Category category, boolean isHidden) {
        this.category = category;
        this.isHidden = isHidden
    }

    @ManyToOne
    @JoinColumn
    private Category category;

    private boolean isHidden;
}

现在我正在执行此操作,以过滤与CategoryController中的类别关联的帖子

@GetMapping
    public List<Category> list(Authentication authentication) {
        boolean canViewHidden = securityService.hasAuthority(Permissions.Post.VIEWHIDDEN, authentication.getAuthorities());
        List<Category> categories = categoryRepository.findAll();
        categories.forEach(
            category -> {
                Set<Post> filteredPosts = category.getPosts().stream()
                    .filter(post -> canViewHidden || !post.isHidden())
                    .collect(Collectors.toSet());
                category.setPosts(filteredPosts);
            }
        );
        return categories;
    }

1 个答案:

答案 0 :(得分:1)

我会尝试在JPA存储库中为Post类使用自定义查询,如下所示:

@Query(value = "SELECT p FROM Post p INNER JOIN Category c ON p.id = c.post.id "
        + "WHERE p.hidden = false AND c.id = :id")
List<Post> findViewablePostsByCategory(@Param("id") Long categoryId);

我知道这可能不是您正在寻找的确切方法,但正如K.Nicholas指出的那样,无法将联接与JPA存储库的查询构建方法一起使用。