Spring Data JPA поиск по встроенному свойству объекта

101

Я хочу написать сигнатуру метода интерфейса репозитория Spring Data JPA, которая позволит мне найти сущности со свойством встроенного объекта в этой сущности. Кто-нибудь знает, возможно ли это, и если да, то как?

Вот мой код:

@Entity
@Table(name = "BOOK_UPDATE_QUEUE", indexes = { uniqueConstraints = @UniqueConstraint(columnNames = {
        "bookId", "region" }, name = "UK01_BOOK_UPDATE_QUEUE"))
public class QueuedBook implements Serializable {

    @Embedded
    @NotNull
    private BookId bookId;

    ...

}

@Embeddable
public class BookId implements Serializable {

    @NotNull
    @Size(min=1, max=40)
    private String bookId;

    @NotNull
    @Enumerated(EnumType.STRING)
    private Region region;

    ...

}

public interface QueuedBookRepo extends JpaRepository<QueuedBook, Long> {

    //I'd like to write a method like this, but can't figure out how to search by region,
    //when region is actually a part of the embedded BookId
    Page<QueuedBook> findByRegion(Region region, Pageable pageable);

}

Могу ли я написать для этого запрос с помощью Spring Data?

CorayThan
источник
4
Не findByBookIdRegion(Region region, Pageable pageable)получается?
Оливер Дротбом
2
Да, это так. Я нигде не мог найти документации по этому поводу. Это скрыто или подразумевается где-то, чего я не видел?
CorayThan
Превратил это в ответ и добавил ссылку на соответствующий раздел справочной документации.
Оливер Дротбом

Ответы:

145

Это имя метода должно помочь:

Page<QueuedBook> findByBookIdRegion(Region region, Pageable pageable);

Подробнее об этом в разделе о формировании запросов справочной документации.

Оливер Дротбом
источник
11
Что делать, если у меня есть список Embeddable? или коллекция элементов?
user962206
Если нам нужен запрос findBy с 3 препертами, то каким будет синтаксис? это как findByPro1AndPro2AndPro3?
surendrapanday
Всегда ли такой запрос приводит к внутреннему соединению? Я делаю One findByIdAndTwoId(Long oneId, Long twoId);и получаю запрос в форме:select ...... from one one_ left outer join two two_ on one_.two_id = two_.id where one_id = ? and two_.id = ?
TroJaN
44

Вышеупомянутое - findByBookIdRegion () у меня не сработало. Следующее работает с последней версией String Data JPA:

Page<QueuedBook> findByBookId_Region(Region region, Pageable pageable);
Bazinga
источник
3
Ваши случаи могут быть связаны с двусмысленностью, как описано на docs.spring.io/spring-data/jpa/docs/current/reference/html/…
Марчелло де Сэйлз
9

Если вы используете BookId в качестве комбинированного первичного ключа, не забудьте изменить свой интерфейс с:

public interface QueuedBookRepo extends JpaRepository<QueuedBook, Long> {

кому:

public interface QueuedBookRepo extends JpaRepository<QueuedBook, BookId> {

И измените аннотацию @Embedded на @EmbeddedId в своем классе QueuedBook следующим образом:

public class QueuedBook implements Serializable {

@EmbeddedId
@NotNull
private BookId bookId;

...
Тим Кара
источник
1

По моему мнению, Spring не во всех случаях легко справляется. В вашем случае следующее должно помочь

Page<QueuedBook> findByBookIdRegion(Region region, Pageable pageable);  

или

Page<QueuedBook> findByBookId_Region(Region region, Pageable pageable);

Однако это также зависит от соглашения об именах полей, которые у вас есть в вашем @Embeddableклассе,

например, следующее поле может не работать ни в одном из стилей, упомянутых выше

private String cRcdDel;

Я пробовал с обоими случаями (как показано ниже), и это не сработало (похоже, что Spring не обрабатывает этот тип соглашений об именах (то есть для многих заглавных букв, особенно в начале - 2-я буква (не уверен, что это хотя единственный случай)

Page<QueuedBook> findByBookIdCRcdDel(String cRcdDel, Pageable pageable); 

или

Page<QueuedBook> findByBookIdCRcdDel(String cRcdDel, Pageable pageable);

Когда я переименовал столбец в

private String rcdDel;

мои следующие решения работают нормально без каких-либо проблем:

Page<QueuedBook> findByBookIdRcdDel(String rcdDel, Pageable pageable); 

ИЛИ

Page<QueuedBook> findByBookIdRcdDel(String rcdDel, Pageable pageable);
Бхавик
источник