web-dev-qa-db-fra.com

Spring Data JPA trouver par propriété d'objet incorporé

Je souhaite écrire une signature de méthode d'interface de référentiel Spring Data JPA qui me permettra de rechercher des entités possédant la propriété d'un objet incorporé dans cette entité. Est-ce que quelqu'un sait si c'est possible, et si oui comment?

Voici mon 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);

}

Puis-je écrire une requête pour cela à l'aide de Spring Data?

89
CorayThan

Ce nom de méthode devrait faire l'affaire:

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

Plus d'informations à ce sujet dans la section sur dérivation de la requête des documents de référence.

128
Oliver Drotbohm

Le précédent - findByBookIdRegion () n'a pas fonctionné pour moi. Ce qui suit fonctionne avec la dernière version de String Data JPA:

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

Si vous utilisez BookId en tant que clé primaire combinée, n'oubliez pas de modifier votre interface en:

public interface QueuedBookRepo extends JpaRepository<QueuedBook, Long> {

à:

public interface QueuedBookRepo extends JpaRepository<QueuedBook, BookId> {

Et changez l'annotation @Embedded en @EmbeddedId, dans votre classe QueuedBook, comme suit:

public class QueuedBook implements Serializable {

@EmbeddedId
@NotNull
private BookId bookId;

...
8
Tim Kara

Selon moi, Spring ne gère pas facilement tous les cas. Dans votre cas, ce qui suit devrait faire l'affaire

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

ou

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

Cependant, cela dépend aussi de la convention de nommage des champs que vous avez dans votre classe @Embeddable.

par exemple. le champ suivant peut ne fonctionner dans aucun des styles mentionnés ci-dessus

private String cRcdDel;

J'ai essayé avec les deux cas (comme suit) et cela n'a pas fonctionné (il semble que Spring ne gère pas ce type de conventions de dénomination (c'est-à-dire avec de nombreuses majuscules, surtout au début - 2e lettre (je ne sais pas si c'est le seul cas cependant)

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

ou

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

Quand j'ai renommé la colonne en

private String rcdDel;

mes solutions suivantes fonctionnent bien sans problème:

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

OR

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