Как отфильтровать поле OneToMany с помощью Spring Data JPA? - PullRequest
0 голосов
/ 26 мая 2019

Я пытаюсь отфильтровать сообщения, связанные с категорией, в зависимости от того, является ли сообщение скрытым или нет.

Я могу сделать это с помощью фильтра пост-запроса (см. Ниже), но мне было интересно, возможно ли построить запрос с использованием методов JPA?(В частности, методы построения запросов, такие как FindAllBy ..., я надеюсь сохранить независимость базы данных, придерживаясь этих типов запросов)

Я также мог бы, вероятно, вызвать FindAllByCategory в PostRepository и сконструировать возврат таким образом, ноэто кажется хакерским и задом наперед.

Итак, чтобы подвести итог, я хотел бы найти способ объявить 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;
}

Сейчас я делаю это, чтобы отфильтровать записи, связанные с категориями, в контроллере категорий

@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 Ответ

1 голос
/ 04 июня 2019

Я бы попробовал использовать пользовательский запрос в вашем JPA-репозитории для класса почты, например:

@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.

...