Spring Data JPA ditemukan berdasarkan properti objek yang disematkan

101

Saya ingin menulis tanda tangan metode antarmuka repositori JPA Spring Data yang memungkinkan saya menemukan entitas dengan properti objek yang disematkan dalam entitas itu. Adakah yang tahu apakah ini mungkin, dan jika demikian bagaimana?

Ini kode saya:

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

}

Dapatkah saya menulis kueri untuk ini menggunakan Spring Data?

CorayThan
sumber
4
Tidak findByBookIdRegion(Region region, Pageable pageable)berhasil?
Oliver Drotbohm
2
Ya, berhasil. Saya tidak dapat menemukan dokumentasi untuk itu di mana pun. Apakah itu tersembunyi atau tersirat di suatu tempat yang tidak saya lihat?
CorayThan
Mengubahnya menjadi jawaban dan menambahkan tautan ke bagian yang relevan dari dokumen referensi.
Oliver Drotbohm

Jawaban:

145

Nama metode ini harus melakukan trik:

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

Info lebih lanjut tentang itu di bagian tentang derivasi kueri dari dokumen referensi.

Oliver Drotbohm
sumber
11
Bagaimana jika saya memiliki daftar yang Dapat Disematkan? atau koleksi elemen?
user962206
Jika kita ingin query findBy dengan 3 preperty lalu apa sintaksnya? apakah itu seperti findByPro1AndPro2AndPro3?
surendrapanday
Apakah kueri seperti itu selalu menghasilkan gabungan dalam? Saya melakukan One findByIdAndTwoId(Long oneId, Long twoId);dan menghasilkan query dalam bentuk:select ...... from one one_ left outer join two two_ on one_.two_id = two_.id where one_id = ? and two_.id = ?
TroJaN
44

Di atas - findByBookIdRegion () tidak berhasil untuk saya. Yang berikut berfungsi dengan rilis terbaru dari String Data JPA:

Page<QueuedBook> findByBookId_Region(Region region, Pageable pageable);
Bazinga
sumber
3
Kasus Anda mungkin terkait dengan ambiguitas seperti yang dibahas di docs.spring.io/spring-data/jpa/docs/current/reference/html/…
Marcello de Sales
9

Jika Anda menggunakan BookId sebagai kunci utama gabungan, ingatlah untuk mengubah antarmuka Anda dari:

public interface QueuedBookRepo extends JpaRepository<QueuedBook, Long> {

untuk:

public interface QueuedBookRepo extends JpaRepository<QueuedBook, BookId> {

Dan ubah anotasi @Embedded menjadi @EmbeddedId, di kelas QueuedBook Anda seperti ini:

public class QueuedBook implements Serializable {

@EmbeddedId
@NotNull
private BookId bookId;

...
Tim Kara
sumber
1

Menurut saya, Spring tidak menangani semua kasus dengan mudah. Dalam kasus Anda, berikut ini harus dilakukan

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

atau

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

Namun, itu juga tergantung pada konvensi penamaan bidang yang Anda miliki di @Embeddablekelas Anda ,

mis. bidang berikut mungkin tidak berfungsi dalam salah satu gaya yang disebutkan di atas

private String cRcdDel;

Saya mencoba dengan kedua kasus (sebagai berikut) dan tidak berhasil (sepertinya Spring tidak menangani jenis konvensi penamaan ini (yaitu untuk banyak Caps, terutama di awal - huruf ke-2 (tidak yakin apakah ini satu-satunya kasus)

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

atau

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

Saat saya mengganti nama kolom menjadi

private String rcdDel;

solusi berikut saya berfungsi dengan baik tanpa masalah apa pun:

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

ATAU

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