2011-03-18 4 views
6

bir listesini döndürür. Geri dönen liste, DB'de aynı sorguyu yaptığım gibi kayıtların/nesnelerin tam sayısını içerir, ancak sorun, tüm nesnelerin aynı/özdeş olmasıdır.hazırda TypedQuery.getResultList() İşte sorunun daha ve belki daha iyi açıklamasıdır aynı nesneye

Örn: Bu, DB'deki sonuçtur (boş değerleri kaldırdım):
26801 01-JAN-00 7 31-DEC-99 7 Obere Kirchstr. 26 CH 8304 Walliselln
26.801 01-OCA-00 2 31-ARA-99 2 Obere Kirchstr. 26 CH 8304 Walliselln

ve bu sorgu yürütüldükten sonra ayıklama sırasında Eclipse görebilirsiniz olarak değişken adres içeriği:

adresleri ArrayList (id = 81)
elementData Nesnesi [ 10] (id = 86)
[0] DLDBAddress (id = 82)
[1] DLDBAddress (id = 82)
[2] boş
...
modCount 1
boyutu 2

DLDBAddress [persid = 26801, valPeriodStart = 1900-01-01, valPeriodEnd = 9999-12-31, addressNr = 7, addressType = 7, addressRow1 = null, addressRow2 = Obere Kirchstr. 26, addressRow3 = null, ülke = CH, posta kodu = 8304, şehir = Walliselln, phoneNr = sıfır, faxNr = sıfır, sekretaryPhoneNr = sıfır, alternatPhoneNr = sıfır, pagerNr = null]

DLDBAddress [persid = 26.801, valPeriodStart = 1900-01-01, valPeriodEnd = 9999-12-31, addressNr = 7, addressType = 7, addressRow1 = null, addressRow2 = Obere Kirchstr. 26 addressRow3 = null, ülke = CH, PostalCode = 8.304, şehir = Walliselln, phoneNr = null, faxNr = null, sekretaryPhoneNr = null, alternatPhoneNr = null, pagerNr = null]]

Gördüğünüz gibi, iki nesneler aynıdır. Bunlar yerine

Bu

Ben sorgu oluşturmak kod parçasıdır ... addressNr ve AddressType farklı shoul:

public static <T> List<T> findBy(EntityManager eM, Class<T> boClass, String whereClause, String whereValue) 
{ 
    EntityManager entityManager = eM; 
    Query query = entityManager.createQuery("from " + boClass.getName() + " s where s." + whereClause + " = " + whereValue); 
    ... 
    return (List<T>) query.getResultList(); 
} 

ve bu (oldukça basit) çıkan sorgu:

den

ch.ethz.id.wai.pdb.bo.DLDBAddress s burada s.persid = 26801

Bu oluşturulan sorgu:

Hibernate: 
select 
dldbaddres0_.PERSID as PERSID0_, 
dldbaddres0_.ADRNUM as ADRNUM0_, 
dldbaddres0_.ADRZEIL1 as ADRZEIL3_0_, 
dldbaddres0_.ADRZEIL2 as ADRZEIL4_0_, 
dldbaddres0_.ADRZEIL3 as ADRZEIL5_0_, 
dldbaddres0_.ADRTYP as ADRTYP0_, 
dldbaddres0_.ADRAUSWTEL as ADRAUSWTEL0_, 
dldbaddres0_.ADRORT as ADRORT0_, 
dldbaddres0_.ADRLAND as ADRLAND0_, 
dldbaddres0_.ADRFAX as ADRFAX0_, 
dldbaddres0_.ADRPSA as ADRPSA0_, 
dldbaddres0_.ADRTEL as ADRTEL0_, 
dldbaddres0_.ADRPLZ as ADRPLZ0_, 
dldbaddres0_.ADRSEKTEL as ADRSEKTEL0_, 
dldbaddres0_.BISDAT as BISDAT0_, 
dldbaddres0_.VONDAT as VONDAT0_ 
from 
NETHZ.V_DLDB_ADRESSE dldbaddres0_ 
where 
dldbaddres0_.PERSID=26801 

Ve burada varlık:

@Entity 
@Table(name = "V_DLDB_ADRESSE", schema="NETHZ") 
public class DLDBAddress 
{ 
    @Id 
    @Column(name = "PERSID", insertable = false, updatable = false) 
    private Integer persid; 
    @Temporal(TemporalType.DATE) 
    @Column(name = "VONDAT", insertable = false, updatable = false) 
    private Date valPeriodStart; 
    @Temporal(TemporalType.DATE) 
    @Column(name = "BISDAT", insertable = false, updatable = false) 
    private Date valPeriodEnd; 
    @Column(name = "ADRNUM", insertable = false, updatable = false) 
    private Integer addressNr; 
    @Column(name = "ADRTYP", insertable = false, updatable = false) 
    private Integer addressType; 
    @Column(name = "ADRZEIL1", insertable = false, updatable = false) 
    private String addressRow1; 
    @Column(name = "ADRZEIL2", insertable = false, updatable = false) 
    private String addressRow2; 
    @Column(name = "ADRZEIL3", insertable = false, updatable = false) 
    private String addressRow3; 
    @Column(name = "ADRLAND", insertable = false, updatable = false) 
    private String country; 
    @Column(name = "ADRPLZ", insertable = false, updatable = false) 
    private String postalCode; 
    @Column(name = "ADRORT", insertable = false, updatable = false) 
    private String city; 
    @Column(name = "ADRTEL", insertable = false, updatable = false) 
    private String phoneNr; 
    @Column(name = "ADRFAX", insertable = false, updatable = false) 
    private String faxNr; 
    @Column(name = "ADRSEKTEL", insertable = false, updatable = false) 
    private String secretaryPhoneNr; 
    @Column(name = "ADRAUSWTEL", insertable = false, updatable = false) 
    private String alternatPhoneNr; 
    @Column(name = "ADRPSA", insertable = false, updatable = false) 
    private String pagerNr; 

... 

mıyım şey eksik?

Ah, Oracle DB için bağlıyorum. peşin Francesco

+0

1. Sorguların okunması daha kolay olduğundan, hql'yi CriteriaBuilder'den kullanma olasılığı daha yüksektir. 2. Yöntemin nereye geçtiğini görmeden, neyin yanlış olduğunu söylemek zor olurdu. – Speck

+1

Deneyimimde, JPA ve Hazırda Bekletme EntityManager'ı kullanarak, kimlik gerçekten benzersiz olmadığında olur, bu JPA'da zorunludur. Hazırda Beklet EntityManager, JPA 2'yi tam olarak uygular. Varlıklarınızı da gönderir misiniz? – Erik

+1

Hazırda Bekletme tarafından oluşturulan gerçek SQL nedir? Bu bilgileri göstermek için Hazırda Bekletme yapılandırmanızı değiştirin. Bu, neyin yanlış gittiğine dair daha iyi bir açıklama sağlayabilir. –

cevap

16
where dldbaddres0_.PERSID=26801 

@Id 
    @Column(name = "PERSID", insertable = false, updatable = false) 

yılında

teşekkürler Bir birincil anahtardır @id olarak PERSID tanımladı. Uygulamanız için gerçekten eşsiz mi? Davranıştan değil. Fakat Hib için mutlaka olmalı.

ne olur:

  1. Sen bunları sorgulamak PERSID = 26801
  2. ile veritabanında iki + kayıtları var NEREDE PERSID = 26801
  3. SQL Query iki + satırları
  4. Hib yükler ilki döndürür ve anahtar olarak PERSID ile oturum açar (çünkü @Id olarak işaretlenmiştir). Nesne, sonuç listesine yerleştirilir.
  5. Hib, ikincisini yükler, aynı @Id'ye sahip bir nesnenin zaten oturumda olduğunu fark eder ve referansı yalnızca Sonuç Listesine yerleştirir. Satır verileri yok sayılır.
  6. Böylece iki + kopya elde edersiniz.
+0

Mükemmel cevap. Güzel bir açıklama. 6 puan için +1. – OO7

İlgili konular