it-swarm-id.com

Permintaan Hibernate Dengan Contoh dan Proyeksi

Singkatnya: hibernate tidak mendukung proyeksi dan permintaan dengan contoh? Saya menemukan posting ini:

Kode ini adalah ini:

User usr = new User();
usr.setCity = 'TEST';
getCurrentSession().createCriteria(User.class)
.setProjection( Projections.distinct( Projections.projectionList()
.add( Projections.property("name"), "name")
.add( Projections.property("city"), "city")))
.add( Example.create(usr))

Seperti kata poster lain, sql yang dihasilkan terus memiliki kelas di mana merujuk hanya y0_ =? alih-alih this_.city

Saya sudah mencoba beberapa pendekatan, dan mencari pelacak masalah tetapi tidak menemukan apa pun tentang ini.

Saya bahkan mencoba menggunakan alias Proyeksi dan Transformer, tetapi tidak berfungsi:

User usr = new User();
usr.setCity = 'TEST';
getCurrentSession().createCriteria(User.class)
.setProjection( Projections.distinct( Projections.projectionList()
.add( Projections.property("name"), "name")
.add( Projections.property("city"), "city")))
.add( Example.create(usr)).setResultTransformer(Transformers.aliasToBean(User.class));

Adakah yang menggunakan proyeksi dan permintaan dengan contoh?

21
Miguel Ping

Bisakah saya melihat kelas Pengguna Anda? Ini hanya menggunakan batasan di bawah ini. Saya tidak melihat mengapa Pembatasan akan benar-benar berbeda dari Contoh (Saya pikir bidang nol diabaikan secara default dalam contoh).

getCurrentSession().createCriteria(User.class)
.setProjection( Projections.distinct( Projections.projectionList()
.add( Projections.property("name"), "name")
.add( Projections.property("city"), "city")))
.add( Restrictions.eq("city", "TEST")))
.setResultTransformer(Transformers.aliasToBean(User.class))
.list();

Saya tidak pernah menggunakan alaistToBean, tetapi saya baru saja membacanya. Anda juga bisa mengulangi hasilnya ..

List<Object> rows = criteria.list();
for(Object r: rows){
  Object[] row = (Object[]) r;
  Type t = ((<Type>) row[0]);
}

Jika perlu, Anda dapat secara manual mengisi sendiri Pengguna dengan cara itu.

Agak sulit untuk melihat masalah tanpa informasi lebih lanjut untuk mendiagnosis masalah tersebut.

16
Arthur Thomas

Masalahnya tampaknya terjadi ketika Anda memiliki alias nama yang sama dengan properti objek. Hibernate tampaknya mengambil alias dan menggunakannya di sql. Saya menemukan ini didokumentasikan sini dan sini , dan saya percaya ini adalah bug di Hibernate, walaupun saya tidak yakin bahwa tim Hibernate setuju.

Either way, saya telah menemukan pekerjaan sederhana di sekitar yang berfungsi dalam kasus saya. Jarak tempuh Anda mungkin beragam. Detailnya di bawah, saya mencoba menyederhanakan kode untuk sampel ini, jadi saya minta maaf atas kesalahan atau kesalahan ketik:

Criteria criteria = session.createCriteria(MyClass.class)
    .setProjection(Projections.projectionList()
        .add(Projections.property("sectionHeader"), "sectionHeader")
        .add(Projections.property("subSectionHeader"), "subSectionHeader")
        .add(Projections.property("sectionNumber"), "sectionNumber"))
    .add(Restrictions.ilike("sectionHeader", sectionHeaderVar)) // <- Problem!
    .setResultTransformer(Transformers.aliasToBean(MyDTO.class));

Akan menghasilkan sql ini:

select
    this_.SECTION_HEADER as y1_,
    this_.SUB_SECTION_HEADER as y2_,
    this_.SECTION_NUMBER as y3_,
from
    MY_TABLE this_ 
where
    ( lower(y1_) like ? ) 

Yang menyebabkan kesalahan: Java.sql.SQLException: ORA-00904: "Y1_": pengidentifikasi tidak valid

Tapi, ketika saya mengubah batasan saya untuk menggunakan "ini", seperti:

Criteria criteria = session.createCriteria(MyClass.class)
    .setProjection(Projections.projectionList()
        .add(Projections.property("sectionHeader"), "sectionHeader")
        .add(Projections.property("subSectionHeader"), "subSectionHeader")
        .add(Projections.property("sectionNumber"), "sectionNumber"))
    .add(Restrictions.ilike("this.sectionHeader", sectionHeaderVar)) // <- Problem Solved!
    .setResultTransformer(Transformers.aliasToBean(MyDTO.class));

Ini menghasilkan sql berikut dan masalah saya terpecahkan.

select
    this_.SECTION_HEADER as y1_,
    this_.SUB_SECTION_HEADER as y2_,
    this_.SECTION_NUMBER as y3_,
from
    MY_TABLE this_ 
where
    ( lower(this_.SECTION_HEADER) like ? ) 

Itu dia! Perbaikan yang cukup sederhana untuk masalah yang menyakitkan. Saya tidak tahu bagaimana perbaikan ini akan diterjemahkan ke kueri dengan masalah contoh, tetapi mungkin membuat Anda lebih dekat.

44
Ryan Cook

Masalah sebenarnya di sini adalah ada bug di hibernate di mana ia menggunakan alias daftar-pilih di mana-klausa:

http://opensource.atlassian.com/projects/hibernate/browse/HHH-817

Untuk berjaga-jaga seandainya seseorang mendarat di sini untuk mencari jawaban, lihat tiketnya. Butuh 5 tahun untuk memperbaikinya tetapi secara teori itu akan ada di salah satu rilis berikutnya dan kemudian saya curiga masalah Anda akan hilang.

6
Dobes Vandermeer

Saya menghadapi masalah yang sama. Saya menggunakan Query dengan Contoh dan saya ingin mengurutkan hasil berdasarkan bidang khusus. Dalam SQL saya akan melakukan sesuatu seperti:

select pageNo, abs(pageNo - 434) as diff
from relA
where year = 2009
order by diff

Ini berfungsi dengan baik tanpa urutan-oleh-klausa. Apa yang saya dapatkan adalah

Criteria crit = getSession().createCriteria(Entity.class);
crit.add(exampleObject);
ProjectionList pl = Projections.projectionList();
pl.add( Projections.property("id") );
pl.add(Projections.sqlProjection("abs(`pageNo`-"+pageNo+") as diff", new String[] {"diff"}, types ));
crit.setProjection(pl);

Tetapi ketika saya menambahkan 

crit.addOrder(Order.asc("diff"));

Saya mendapatkan org.hibernate.QueryException: tidak dapat menyelesaikan properti: diff exception. Penanganan masalah dengan ini juga tidak berhasil. 

PS: karena saya tidak bisa menemukan dokumentasi yang rumit tentang penggunaan QBE untuk Hibernate, semua hal di atas terutama pendekatan coba-coba

0
VHristov
ProjectionList pl = Projections.projectionList();
pl.add(Projections.property("id"));
pl.add(Projections.sqlProjection("abs(`pageNo`-" + pageNo + ") as diff", new String[] {"diff"}, types ), diff); ---- solution
crit.addOrder(Order.asc("diff"));
crit.setProjection(pl);
0
singh