Spring Data JPA znajduje się na podstawie właściwości obiektu osadzonego


101

Chcę napisać sygnaturę metody interfejsu repozytorium Spring Data JPA, która pozwoli mi znaleźć jednostki z właściwością obiektu osadzonego w tej jednostce. Czy ktoś wie, czy jest to możliwe, a jeśli tak, to w jaki sposób?

Oto mój kod:

@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);

}

Czy mogę napisać zapytanie za pomocą Spring Data?


4
Nie findByBookIdRegion(Region region, Pageable pageable)załatwia sprawy?
Oliver Drotbohm

2
Tak, to wszystko. Nigdzie nie mogłem znaleźć na to dokumentacji. Czy jest ukryty lub sugerowany w miejscu, którego nie widziałem?
CorayThan

Przekształciłem to w odpowiedź i dodałem link do odpowiedniej sekcji dokumentów referencyjnych.
Oliver Drotbohm

Odpowiedzi:


145

Ta nazwa metody powinna załatwić sprawę:

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

Więcej informacji na ten temat w sekcji dotyczącej wyprowadzania zapytań w dokumentach referencyjnych.


11
A jeśli mam listę elementów do osadzania? czy kolekcja elementów?
user962206

Jeśli chcemy, aby zapytanie findBy miało 3 preperty, jaka będzie składnia? czy to jest jak findByPro1AndPro2AndPro3?
surendrapanday

Czy takie zapytanie zawsze skutkuje sprzężeniem wewnętrznym? Robię One findByIdAndTwoId(Long oneId, Long twoId);i skutkuje zapytaniem w postaci:select ...... from one one_ left outer join two two_ on one_.two_id = two_.id where one_id = ? and two_.id = ?
TroJaN


9

Jeśli używasz BookId jako połączonego klucza podstawowego, pamiętaj, aby zmienić interfejs z:

public interface QueuedBookRepo extends JpaRepository<QueuedBook, Long> {

do:

public interface QueuedBookRepo extends JpaRepository<QueuedBook, BookId> {

I zmień adnotację @Embedded na @EmbeddedId w swojej klasie QueuedBook w następujący sposób:

public class QueuedBook implements Serializable {

@EmbeddedId
@NotNull
private BookId bookId;

...

1

Według mnie Spring nie radzi sobie z łatwością we wszystkich przypadkach. W twoim przypadku poniższe powinny załatwić sprawę

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

lub

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

Zależy to jednak również od konwencji nazewnictwa pól, które masz w swojej @Embeddableklasie,

np. poniższe pole może nie działać w żadnym ze stylów wymienionych powyżej

private String cRcdDel;

Próbowałem z obydwoma przypadkami (jak poniżej) i nie zadziałało (wygląda na to, że Spring nie obsługuje tego typu konwencji nazewnictwa (tj. Do wielu Caps, szczególnie na początku - druga litera) (nie jestem pewien, czy to jest jedyny przypadek)

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

lub

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

Kiedy zmieniłem nazwę kolumny na

private String rcdDel;

moje następujące rozwiązania działają dobrze bez problemu:

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

LUB

Page<QueuedBook> findByBookIdRcdDel(String rcdDel, Pageable pageable);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.