Spring Data JPA-Suche nach eingebetteter Objekteigenschaft


101

Ich möchte eine Signatur der Spring Data JPA-Repository-Schnittstellenmethode schreiben, mit der ich Entitäten mit der Eigenschaft eines eingebetteten Objekts in dieser Entität finden kann. Weiß jemand, ob und wie dies möglich ist?

Hier ist mein Code:

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

}

Kann ich mit Spring Data eine Abfrage dazu schreiben?


4
Macht findByBookIdRegion(Region region, Pageable pageable)den Trick nicht?
Oliver Drotbohm

2
Ja, das macht es. Ich konnte nirgendwo eine Dokumentation dafür finden. Ist es irgendwo versteckt oder impliziert, was ich nicht gesehen habe?
CorayThan

Verwandelte dies in eine Antwort und fügte einen Link zum entsprechenden Abschnitt der Referenzdokumente hinzu.
Oliver Drotbohm

Antworten:


145

Dieser Methodenname sollte den Trick machen:

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

Weitere Informationen hierzu finden Sie im Abschnitt zur Ableitungsableitung der Referenzdokumente.


11
Was ist, wenn ich eine Liste von Embeddable habe? oder Elementsammlung?
user962206

Wenn wir eine findBy-Abfrage mit 3 Eigenschaften wünschen, wie lautet dann die Syntax? ist es wie findByPro1AndPro2AndPro3?
Surendrapanday

Führt eine solche Abfrage immer zu einem inneren Join? Ich mache One findByIdAndTwoId(Long oneId, Long twoId);und führt zu einer Abfrage des Formulars:select ...... from one one_ left outer join two two_ on one_.two_id = two_.id where one_id = ? and two_.id = ?
TroJaN


9

Wenn Sie BookId als kombinierten Primärschlüssel verwenden, müssen Sie die Benutzeroberfläche folgendermaßen ändern:

public interface QueuedBookRepo extends JpaRepository<QueuedBook, Long> {

zu:

public interface QueuedBookRepo extends JpaRepository<QueuedBook, BookId> {

Ändern Sie die Anmerkung @Embedded in Ihrer QueuedBook-Klasse wie folgt in @EmbeddedId:

public class QueuedBook implements Serializable {

@EmbeddedId
@NotNull
private BookId bookId;

...

1

Meiner Meinung nach behandelt Spring nicht alle Fälle mit Leichtigkeit. In Ihrem Fall sollte das Folgende den Trick tun

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

oder

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

Dies hängt jedoch auch von der Namenskonvention der Felder in Ihrer @EmbeddableKlasse ab.

Beispiel: Das folgende Feld funktioniert möglicherweise nicht in einem der oben genannten Stile

private String cRcdDel;

Ich habe es mit beiden Fällen versucht (wie folgt) und es hat nicht funktioniert (es scheint, als würde Spring diese Art von Namenskonventionen nicht verarbeiten (dh zu viele Großbuchstaben, insbesondere am Anfang - 2. Buchstabe (nicht sicher, ob dies der Fall ist) der einzige Fall jedoch)

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

oder

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

Als ich die Spalte in umbenannt habe

private String rcdDel;

Meine folgenden Lösungen funktionieren ohne Probleme:

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

ODER

Page<QueuedBook> findByBookIdRcdDel(String rcdDel, Pageable pageable);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.