Spring JPA - findAll () с примером / зондом, включающим связанный / присоединенный объект - PullRequest
0 голосов
/ 04 июня 2019

Как можно использовать запрос Spring JPA на примере для запроса не только самой сущности, но и свойств связанной сущности с использованием findAll()? Кажется, что все наши попытки просто игнорируют свойства связанных сущностей, когда они установлены в сущности probe / example.

В документации указано:

Спецификатор свойства принимает имена свойств (например, имя и фамилия). Вы можете перемещаться по цепочке свойств вместе с точками (address.city). Вы также можете настроить его с помощью соответствующих параметров и чувствительности к регистру.

Однако нет примера, показывающего, как должна работать цепочка, и наши попытки ее использовать не принесли успеха.

Придуманный пример

Предполагая структуру базы данных с отношением «многие ко многим»

  • Таблица: Книга

    • id (PK, INT)
    • title (varchar)
    • ...
  • Таблица: Категория

    • id (PK, INT)
    • имя
    • ...
  • Таблица: Book_Category

    • book_id
    • category_id

Book.java

@Data
@Entity
public class Book {
    public Book () {}
    public Book(String title, List<Category> categories) {
        this.title = title;
        this.categories = categories;
    }

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

    @NotNull
    private String title;

    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinTable(
        name = "book_category",
        joinColumns = {@JoinColumn(name = "book_id")},
        inverseJoinColumns = {@JoinColumn(name = "category_id")}
    )
    private List<Category> categories;
}

BookRepository.java

@Repository
public class BookRepository extends JpaRepository<Book, long> {

}

Category.java

@Data
@Entity
public class Category {

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

    @NotNull
    private String name;
}

CategoryRepository.java

@Repository
public class CategoryRepository extends JpaRepository<Category, long> {

}

BookService.java

public class BookService {
    @Autowired
    private BookRepository bookRepository;

    @Autowired
    private CategoryRepository categoryRepository;

    public List<Book> findByExample(String title, String category) {
        ExampleMatcher matcher = ExampleMatcher.matchingAll()
            .withMatcher("title", match -> match.contains().ignoreCase()) 
// ### This is (probably?) the bit that's wrong - none of these made any difference        
            //.withMatcher("categories.id", match -> match.contains()) 
            //.withMatcher("categories.name", match -> match.contains().ignoreCase()) 
            //.withMatcher("categories", match -> match.contains()) 
// ###
            .withIgnoreNullValues() // ignore unset properties when finding
            .withIgnorePaths("id"); // ignore primitives as they default to 0

        List<Category> matchingCategories = categoryRepository.findAllByName(category);
        Example<Book> example = Example.of(new Book(
            title, matchingCategories), matcher);

        return bookRepository.findAll(example)
    }
}

Вызов BookService.findByExample (...) корректно фильтрует по заголовку, но полностью игнорирует категорию. «Реальный» пример более сложный, но это устраняет проблему, с которой мы сталкиваемся; как мы можем отфильтровать как связанную таблицу, так и базовую?

1 Ответ

0 голосов
/ 04 июня 2019

Это верно только для отношений ToOne и не работает для ToMany, как в вашем случае:

Спецификатор свойства принимает имена свойств (например, имя и Фамилия). Вы можете перемещаться по цепочке свойств вместе с точками (Адрес Город). Вы также можете настроить его с помощью соответствующих параметров и случая чувствительность.

Я также взглянул на исходный код Spring Data и вот он:

for (SingularAttribute attribute : type.getSingularAttributes()) {

Так что он использует только SingularAttribute, такой как примитивы, отношения String и ToOne.

Так что я боюсь, но то, чего вы пытаетесь достичь, кажется невозможным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...