Menambahkan Daftar klausa IN ke JPA Query

125

Saya telah membuat NamedQuery yang terlihat seperti ini:

@NamedQuery(name = "EventLog.viewDatesInclude",
        query = "SELECT el FROM EventLog el WHERE el.timeMark >= :dateFrom AND "
        + "el.timeMark <= :dateTo AND "
        + "el.name IN (:inclList)")

Yang ingin saya lakukan adalah mengisi parameter: inclList dengan daftar item, bukan satu item. Misalnya jika saya punya new List<String>() { "a", "b", "c" }bagaimana cara mendapatkannya di parameter: inclList? Ini hanya memungkinkan saya menyusun satu string. Sebagai contoh:

setParameter("inclList", "a") // works

setParameter("inclList", "a, b") // does not work

setParameter("inclList", "'a', 'b'") // does not work

setParameter("inclList", list) // throws an exception

Saya tahu saya bisa membuat string dan membangun seluruh Query dari situ, tapi saya ingin menghindari overhead. Apakah ada cara yang lebih baik untuk melakukan ini?

Pertanyaan terkait: jika List sangat besar, adakah cara yang baik untuk membuat kueri seperti itu?

AlanObject
sumber
Ini adalah duplikat dari stackoverflow.com/questions/1557085/… tetapi utas ini memberikan jawaban yang berguna.
Mike Ryan

Jawaban:

181

Saat menggunakan INdengan parameter nilai koleksi, Anda tidak memerlukan (...):

@NamedQuery(name = "EventLog.viewDatesInclude", 
    query = "SELECT el FROM EventLog el WHERE el.timeMark >= :dateFrom AND " 
    + "el.timeMark <= :dateTo AND " 
    + "el.name IN :inclList") 
axtavt
sumber
6
Tidak ... Saya kasus saya sebaliknya. Jika saya menggunakan: inclList maka itu tidak berfungsi. Jika saya menggunakan IN (: inclList) maka itu berhasil.
Gunjan Shah
1
Perhatikan juga menyebutkan: jenis param Anda harus berupa kumpulan (bukan larik) objek. Objek harus sesuai dengan jenis bidang. .toString () bukanlah pengganti kelas String
dube
2
Saya pikir ini adalah sesuatu yang telah berubah dengan versi Hibernate, sejauh yang saya ingat saya mendapatkan kesalahan saat tidak memiliki paranthesis di sekitar variabel saat menggunakan IN. Aneh jika tidak kompatibel ke belakang ..
Tobb
1
Ini memang bug hibernasi (perlu tanda kurung) yang telah diperbaiki di 3.6.1
Mat
1
Untuk pertanyaan terkait: Dalam kasus daftar yang sangat besar, mungkin ada batasan untuk implementasi. Misalnya oracle 11g. maks. 1000 elemen daftar sebagai parameter dimungkinkan. Solusinya adalah memotong daftar di subList dan mengumpulkan hasilnya. JPA sendiri tidak membatasi ukuran daftar.
Mahttias Schrebiér
81

Format kueri JPA yang tepat adalah:

el.name IN :inclList

Jika Anda menggunakan versi Hibernate yang lebih lama sebagai penyedia Anda, Anda harus menulis:

el.name IN (:inclList)

tetapi itu adalah bug ( HHH-5126 ) (EDIT: yang telah diselesaikan sekarang).

Jose Ferrer
sumber
5
Terima kasih telah membedakan penggunaan Hibernate versi lama ()
Rob L
31
public List<DealInfo> getDealInfos(List<String> dealIds) {
        String queryStr = "SELECT NEW com.admin.entity.DealInfo(deal.url, deal.url, deal.url, deal.url, deal.price, deal.value) " + "FROM Deal AS deal where deal.id in :inclList";
        TypedQuery<DealInfo> query = em.createQuery(queryStr, DealInfo.class);
        query.setParameter("inclList", dealIds);
        return query.getResultList();
    }

Bekerja untuk saya dengan JPA 2, Jboss 7.0.2

pengguna1114134
sumber
9

Anda harus mengonversi menjadi Listseperti yang ditunjukkan di bawah ini:

    String[] valores = hierarquia.split(".");       
    List<String> lista =  Arrays.asList(valores);

    String jpqlQuery = "SELECT a " +
            "FROM AcessoScr a " +
            "WHERE a.scr IN :param ";

    Query query = getEntityManager().createQuery(jpqlQuery, AcessoScr.class);                   
    query.setParameter("param", lista);     
    List<AcessoScr> acessos = query.getResultList();
Wesley Rocha
sumber
Terima kasih jawaban ini membantu saya
cabaji99