2011-03-18 15 views
6

की सूची लौटाता है यहाँ समस्या का एक और अधिक और शायद बेहतर वर्णन है:हाइबरनेट - TypedQuery.getResultList() एक ही वस्तु

मैं एक साधारण चयन क्वेरी है। लौटने वाली सूची में रिकॉर्ड्स/ऑब्जेक्ट्स की सटीक संख्या होती है जैसे कि मैं डीबी में एक ही क्वेरी करता हूं, लेकिन समस्या यह है कि सभी ऑब्जेक्ट समान/समान हैं।

पूर्व के लिए, डीबी (मैंने शून्य मान हटा दिए हैं) में परिणाम है:
26801 01-जेएन -00 7 31-डीईसी-99 7 ओबेरे किरचस्ट्र। 26 सीएच 8304 वालिसिन
26801 01-जेएन -00 2 31-डीईसी-99 2 ओबेरे किरचस्ट्र। 26 सीएच 8304 Walliselln

और यह चर पतों की सामग्री के रूप में मैं डीबगिंग के दौरान ग्रहण में देख सकते हैं के बाद क्वेरी निष्पादित किया गया है:

पतों ArrayList (आईडी = 81)
elementData वस्तु [ 10] (आईडी = 86)
[0] DLDBAddress (आईडी = 82)
[1] DLDBAddress (आईडी = 82)
[2] अशक्त
...
modCount 1
आकार 2

डीएलडीबीड्रेस [persid = 26801, valPeriodStart = 1900-01-01, valPeriodEnd = 9999-12-31, addressNr = 7, addressType = 7, addressRow1 = null, addressRow2 = Obere Kirchstr। 26, addressRow3 = अशक्त, देश = सीएच, PostalCode = 8304, शहर = Walliselln, phoneNr = अशक्त, faxNr = अशक्त, sekretaryPhoneNr = अशक्त, alternatPhoneNr = अशक्त, pagerNr = अमान्य]

DLDBAddress [persid = 26801, valPeriodStart = 1 9 00-01-01, valPeriodEnd = 9999-12-31, addressNr = 7, addressType = 7, addressRow1 = null, addressRow2 = Obere Kirchstr। 26, addressRow3 = अशक्त, देश = सीएच, PostalCode = 8304, शहर = Walliselln, phoneNr = अशक्त, faxNr = अशक्त, sekretaryPhoneNr = अशक्त, alternatPhoneNr = अशक्त, pagerNr = अशक्त]]

आप देख सकते हैं, दो वस्तुएं समान हैं। वे बजाय addressNr और addressType से अलग 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(); 
} 

और इस (काफी सरल) परिणामी क्वेरी है:

से ch.ethz.id.wai.pdb.bo.DLDBAddress रों जहां s.persid = 26801

यह उत्पन्न क्वेरी है:

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 

और यहाँ इकाई:

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

... 

Am मैं कुछ याद आ रही?

आह, मैं ओरेकल डीबी से जुड़ रहा हूं।

अग्रिम फ्रांसेस्को

+0

1. मुझे मानदंड बुल्डर के मुकाबले एचक्यूएल का उपयोग करने की अधिक संभावना होगी क्योंकि प्रश्न पढ़ने के लिए आसान हैं। 2. विधि को पारित किया गया खंड देखने के बिना, आपको यह बताना मुश्किल होगा कि क्या गलत है। – Speck

+1

मेरे अनुभव में, जेपीए और हाइबरनेट एंटिटी मैनेजर का उपयोग करके, ऐसा तब होता है जब आईडी वास्तव में अद्वितीय नहीं होती है, जो जेपीए में अनिवार्य है। Hibernate EntityManager पूरी तरह से जेपीए 2 लागू करता है ताकि इसे यहां भी लागू किया जाना चाहिए। क्या आप अपनी संस्थाओं को भी पोस्ट करेंगे? – Erik

+1

हाइबरनेट द्वारा उत्पन्न वास्तविक एसक्यूएल क्या है? उस जानकारी को दिखाने के लिए अपनी हाइबरनेट कॉन्फ़िगरेशन बदलें। इससे गलत क्या हो रहा है के बारे में एक बेहतर स्पष्टीकरण प्रदान कर सकता है। –

उत्तर

16
where dldbaddres0_.PERSID=26801 

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

धन्यवाद आप @Id है, जो एक प्राथमिक कुंजी के रूप में PERSID परिभाषित किया। क्या यह वास्तव में आपके आवेदन के लिए अद्वितीय है? व्यवहार से यह नहीं है। लेकिन हिब के लिए यह होना चाहिए।

तो क्या होता है:

  1. आप PERSID = 26801
  2. साथ डेटाबेस में दो + रिकॉर्ड आप उन्हें क्वेरी कहां PERSID = 26801
  3. एसक्यूएल क्वेरी रिटर्न दो + पंक्तियों
  4. हिब भार पहले एक , और एक कुंजी के रूप में PERSID के साथ सत्र में डालता है (क्योंकि इसे @Id के रूप में चिह्नित किया जाता है)। ऑब्जेक्ट परिणाम सूची में रखा गया है।
  5. हिब दूसरे को लोड करता है, नोटिस करता है कि एक ही ऑब्जेक्ट वाला एक ऑब्जेक्ट पहले ही सत्र में है, और केवल परिणाम सूची में संदर्भ रखता है। पंक्ति डेटा को नजरअंदाज कर दिया जाता है।
  6. इस प्रकार आपको दो + प्रतियां मिलती हैं।
+0

उत्कृष्ट जवाब। अच्छा स्पष्टीकरण। 6 अंक के लिए +1। – OO7

संबंधित मुद्दे