Spring Data JPA埋め込みオブジェクトプロパティによる検索


101

Spring Data JPAリポジトリインターフェイスメソッドシグネチャを記述して、そのエンティティに埋め込まれたオブジェクトのプロパティを持つエンティティを検索できるようにします。これが可能かどうか、そして可能であればどうすればいいですか?

これが私のコードです:

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

}

Spring Dataを使用してこのクエリを作成できますか?


4
findByBookIdRegion(Region region, Pageable pageable)トリックをしませんか?
Oliver Drotbohm 2014年

2
うん、それはそれをします。そのドキュメントはどこにも見つかりませんでした。それは私が見なかったどこかに隠されているか、暗示されていますか?
CorayThan 2014年

それを回答に変え、参照ドキュメントの関連セクションへのリンクを追加しました。
Oliver Drotbohm 2014年

回答:


145

このメソッド名でうまくいくはずです:

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

詳細については、リファレンスドキュメントのクエリ派生に関するセクションをご覧ください。


11
埋め込み可能のリストがある場合はどうなりますか?または要素のコレクション?
user962206

3つのプロパティを持つfindByクエリが必要な場合、構文はどうなるでしょうか。findByPro1AndPro2AndPro3のようなものですか?
スレンドラパンダ

そのようなクエリは常に内部結合になりますか?私がやっているOne findByIdAndTwoId(Long oneId, Long twoId);と、フォームのクエリで結果:select ...... from one one_ left outer join two two_ on one_.two_id = two_.id where one_id = ? and two_.id = ?
トロイの木馬


9

BookIdを結合された主キーとして使用している場合は、インターフェースを次のように変更してください。

public interface QueuedBookRepo extends JpaRepository<QueuedBook, Long> {

に:

public interface QueuedBookRepo extends JpaRepository<QueuedBook, BookId> {

次のように、QueuedBookクラスのアノテーション@Embeddedを@EmbeddedIdに変更します。

public class QueuedBook implements Serializable {

@EmbeddedId
@NotNull
private BookId bookId;

...

1

私によると、Springはすべてのケースを簡単に処理することはできません。あなたの場合、次のことがうまくいくはずです

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

または

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

ただし、@Embeddableクラスにあるフィールドの命名規則にも依存します。

たとえば、次のフィールドは、上記のいずれのスタイルでも機能しない可能性があります

private String cRcdDel;

私は両方の場合(以下のように)を試してみましたが、うまくいきませんでした(Springはこのタイプの命名規則を処理していないようです(つまり、多くの大文字、特に最初の2文字目)-これが正しいかどうかわかりません唯一のケース)

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

または

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

列の名前を

private String rcdDel;

私の次の解決策は問題なくうまく機能します:

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

または

Page<QueuedBook> findByBookIdRcdDel(String rcdDel, Pageable pageable);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.