Spring Data JPA encuentra por propiedad de objeto incrustado

101

Quiero escribir una firma de método de interfaz de repositorio de Spring Data JPA que me permita encontrar entidades con una propiedad de un objeto incrustado en esa entidad. ¿Alguien sabe si esto es posible y, de ser así, cómo?

Aquí está mi código:

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

}

¿Puedo escribir una consulta para esto usando Spring Data?

CorayThan
fuente
4
¿No funciona findByBookIdRegion(Region region, Pageable pageable)?
Oliver Drotbohm
2
Sí, eso es todo. No pude encontrar documentación para eso en ningún lado. ¿Está escondido o implícito en algún lugar que no vi?
CorayThan
Convirtió eso en una respuesta y agregó un enlace a la sección relevante de los documentos de referencia.
Oliver Drotbohm

Respuestas:

145

Este nombre de método debería funcionar:

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

Más información sobre eso en la sección sobre derivación de consultas de los documentos de referencia.

Oliver Drotbohm
fuente
11
¿Qué pasa si tengo una lista de incrustables? o colección de elementos?
user962206
Si queremos findBy query con 3 propiedades, ¿cuál será la sintaxis? ¿es como findByPro1AndPro2AndPro3?
surendrapanday
¿Tal consulta siempre resulta en una combinación interna? Estoy haciendo One findByIdAndTwoId(Long oneId, Long twoId);y da como resultado una consulta de la forma:select ...... from one one_ left outer join two two_ on one_.two_id = two_.id where one_id = ? and two_.id = ?
TroJaN
44

Lo anterior: findByBookIdRegion () no funcionó para mí. Lo siguiente funciona con la última versión de String Data JPA:

Page<QueuedBook> findByBookId_Region(Region region, Pageable pageable);
Bazinga
fuente
3
Sus casos pueden estar relacionados con la ambigüedad como se analiza en docs.spring.io/spring-data/jpa/docs/current/reference/html/…
Marcello de Sales
9

Si está utilizando BookId como una clave primaria combinada, recuerde cambiar su interfaz de:

public interface QueuedBookRepo extends JpaRepository<QueuedBook, Long> {

a:

public interface QueuedBookRepo extends JpaRepository<QueuedBook, BookId> {

Y cambie la anotación @Embedded a @EmbeddedId, en su clase QueuedBook así:

public class QueuedBook implements Serializable {

@EmbeddedId
@NotNull
private BookId bookId;

...
Tim Kara
fuente
1

Según yo, Spring no maneja todos los casos con facilidad. En su caso, lo siguiente debería funcionar

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

o

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

Sin embargo, también depende de la convención de nomenclatura de los campos que tenga en su @Embeddableclase,

Por ejemplo, es posible que el siguiente campo no funcione en ninguno de los estilos mencionados anteriormente.

private String cRcdDel;

Intenté con ambos casos (como sigue) y no funcionó (parece que Spring no maneja este tipo de convenciones de nomenclatura (es decir, muchas mayúsculas, especialmente al principio) - 2da letra (no estoy seguro de si esto es aunque el único caso)

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

o

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

Cuando cambié el nombre de la columna a

private String rcdDel;

mis siguientes soluciones funcionan bien sin ningún problema:

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

O

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