Веб-дані JPA знайдіть за вбудованою властивістю об'єкта


101

Я хочу написати підпис методу інтерфейсу сховища JPA Spring Data, який дозволить мені знайти об'єкти із властивістю вбудованого об'єкта в цій сутності. Хтось знає, чи можливо це, і якщо так, як?

Ось мій код:

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


4
Не findByBookIdRegion(Region region, Pageable pageable)робить трюк?
Олівер Дротбом

2
Так, це і робиться. Я не могла знайти документацію для цього ніде. Це приховано чи мається на увазі десь я не бачив?
CorayThan

Перетворив це у відповідь і додав посилання на відповідний розділ довідкових документів.
Олівер Дротбом

Відповіді:


145

Ім'я цього методу повинно зробити трюк:

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

Більше інформації про це у розділі про отримання запитів довідкових документів.


11
Що робити, якщо у мене є список вбудованих? або колекція елементів?
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


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 не справляється з таким типом умовних імен (тобто для багатьох Caps, особливо на початку - 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);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.