Spring Data JPA trova dalla proprietà dell'oggetto incorporato


101

Desidero scrivere una firma del metodo dell'interfaccia del repository JPA Spring Data che mi consenta di trovare entità con una proprietà di un oggetto incorporato in tale entità. Qualcuno sa se questo è possibile, e se sì come?

Ecco il mio codice:

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

}

Posso scrivere una query per questo utilizzando Spring Data?


4
Non findByBookIdRegion(Region region, Pageable pageable)fa il trucco?
Oliver Drotbohm,

2
Sì, lo fa. Non sono riuscito a trovare documentazione per questo da nessuna parte. È nascosto o implicito da qualche parte che non ho visto?
Coray,

L'ho trasformato in una risposta e ho aggiunto un collegamento alla sezione pertinente dei documenti di riferimento.
Oliver Drotbohm,

Risposte:


145

Questo nome del metodo dovrebbe fare il trucco:

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

Maggiori informazioni a riguardo nella sezione sulla derivazione delle query dei documenti di riferimento.


11
E se ho un elenco di Embeddable? o raccolta di elementi?
user962206

Se vogliamo una query findBy con 3 preperty, quale sarà la sintassi? è come findByPro1AndPro2AndPro3?
surendrapanday

Una query di questo tipo si traduce sempre in un inner join? Sto facendo One findByIdAndTwoId(Long oneId, Long twoId);e risultati in una query del modulo:select ...... from one one_ left outer join two two_ on one_.two_id = two_.id where one_id = ? and two_.id = ?
TroJaN


9

Se stai utilizzando BookId come chiave primaria combinata, ricorda di cambiare la tua interfaccia da:

public interface QueuedBookRepo extends JpaRepository<QueuedBook, Long> {

per:

public interface QueuedBookRepo extends JpaRepository<QueuedBook, BookId> {

E cambia l'annotazione @Embedded in @EmbeddedId, nella tua classe QueuedBook in questo modo:

public class QueuedBook implements Serializable {

@EmbeddedId
@NotNull
private BookId bookId;

...

1

Secondo me, Spring non gestisce tutti i casi con facilità. Nel tuo caso il seguente dovrebbe fare il trucco

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

o

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

Tuttavia, dipende anche dalla convenzione di denominazione dei campi che hai nella tua @Embeddableclasse,

ad esempio, il campo seguente potrebbe non funzionare in nessuno degli stili menzionati sopra

private String cRcdDel;

Ho provato con entrambi i casi (come segue) e non ha funzionato (sembra che Spring non gestisca questo tipo di convenzioni di denominazione (cioè a molti Caps, specialmente all'inizio - 2a lettera (non sono sicuro se questo sia l'unico caso però)

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

o

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

Quando ho rinominato la colonna in

private String rcdDel;

le mie seguenti soluzioni funzionano bene senza alcun problema:

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

O

Page<QueuedBook> findByBookIdRcdDel(String rcdDel, Pageable pageable);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.