2012-08-24 12 views
5

मैं पूछना चाहता हूं, यह संभव है कि मैं एक से अधिक स्तरों के लिए क्वेरी अनुमान और मानदंड तैयार करूं? मैं 2 मॉडल श्रेणियां होती हैं:कॉम्प्लेक्स हाइबरनेट अनुमान

@Entity 
@Table(name = "person") 
public class Person implements Serializable { 
    @Id 
    @GeneratedValue 
    private int personID; 
    private double valueDouble; 
    private int valueInt; 
    private String name; 
    @OneToOne(cascade = {CascadeType.ALL}, orphanRemoval = true) 
    @JoinColumn(name="wifeId") 
    private Wife wife; 
     /* 
     * Setter Getter  
     */ 
} 


@Entity 
@Table(name = "wife") 
public class Wife implements Serializable { 

    @Id 
    @GeneratedValue  
    @Column(name="wifeId") 
    private int id; 
    @Column(name="name") 
    private String name; 
    @Column(name="age") 
    private int age;    
    /* 
    * Setter Getter 
    */  
} 

मेरे मानदंड एपीआई:

ProjectionList projections = Projections.projectionList(); 
projections.add(Projections.property("this.personID"), "personID"); 
projections.add(Projections.property("this.wife"), "wife"); 
projections.add(Projections.property("this.wife.name"), "wife.name"); 

Criteria criteria = null; 
criteria = getHandlerSession().createCriteria(Person.class); 
criteria.createCriteria("wife", "wife", JoinType.LEFT.ordinal()); 
criterion = Restrictions.eq("wife.age", 19); 
criteria.add(criterion); 
criteria.setProjection(projections); 
criteria.setResultTransformer(Transformers.aliasToBean(Person.class)); 
return criteria.list(); 

और मुझे आशा है, मैं व्यक्ति क्वेरी कर सकता है, पत्नी संपत्ति के लिए निर्दिष्ट मापदंड है, और निर्दिष्ट वापसी ResultSet साथ। इसलिए मैंने निर्दिष्ट रिटर्न परिणाम प्राप्त करने के लिए अनुमान लगाए हैं

मुझे व्यक्तिगत आईडी, व्यक्ति (नाम), नाम (पत्नी) वापस आना चाहिए। मुझे एपीआई का उपयोग कैसे करना चाहिए, मैं हाइबरनेट मानदंड API का उपयोग करना पसंद करता हूं।

इस बार, मैं अपने अपेक्षित परिणाम प्राप्त करने के लिए ऊपर दिए गए कोड का इस्तेमाल किया है, लेकिन यह त्रुटि संदेश के साथ अपवाद फेंक देगा: Exception in thread "main" org.hibernate.QueryException: could not resolve property: wife.name of: maladzan.model.Person, और कि मेरे Restrictions.eq("wife.age", 19); व्यक्ति जो 19 उसकी उम्र मूल्य के रूप में साथ पत्नी है प्राप्त करने के लिए सही है?

धन्यवाद

उत्तर

6

AFAIK यह एक से अधिक स्तर aliastobean ट्रांसफार्मर के साथ गहरे परियोजना के लिए संभव नहीं है। आपके विकल्प

  • चपटा डाटा ट्रांसफर वस्तु (डीटीओ)
  • स्मृति में जिसके परिणामस्वरूप व्यक्ति को भरने बनाने हैं अपने आप को
  • अपनी खुद की resulttransformer

विकल्प 1 दिखता है (विकल्प 2 के समान) को लागू इस तरह:

Criteria criteria = getHandlerSession().createCriteria(Person.class) 
    .createAlias("wife", "wife", JoinType.LEFT.ordinal()) 
    .add(Restrictions.eq("wife.age", 19)); 
    .setProjection(Projections.projectionList() 
     .add(Projections.property("personID"), "personID") 
     .add(Projections.property("name"), "personName") 
     .add(Projections.property("wife.name"), "wifeName")); 
    .setResultTransformer(Transformers.aliasToBean(PersonWifeDto.class)); 

return criteria.list(); 
5

मैंने ResultTransformer लिखा, यह वास्तव में ऐसा करता है। इसका नाम AliasToBeanNestedResultTransformer है, इसे github पर देखें।

+0

हाय सामी एंडोनी।मैंने नेस्टेड ऑब्जेक्ट सृजन के लिए आपके एलियास टोबनएस्टेड रेसल्ट ट्रान्सफॉर्मर का उपयोग किया था, मुझे नेस्टेड ऑब्जेक्ट को नेस्टेड ऑब्जेक्ट के रूप में मिलता है, लेकिन मेरे पास एक छोटा सा मुद्दा है। मैं नेस्टेड ऑब्जेक्ट में केवल विशेष फ़ील्ड प्राप्त करना चाहता हूं, पैरेंट ऑब्जेक्ट में केवल कुछ फ़ील्ड, लेकिन परिणाम मूल ऑब्जेक्ट में सभी फ़ील्ड और नेस्टेड ऑब्जेक्ट के सभी फ़ील्ड नेस्टेड ऑब्जेक्ट के रूप में हैं। मुझे नहीं पता कि आपका कस्टम ट्रांसफार्मर केवल एक विशेष क्षेत्र लाने में सक्षम है, क्या नेस्टेड ऑब्जेक्ट में केवल एक विशेष फ़ील्ड को नेस्टेड ऑब्जेक्ट के रूप में लाने के लिए संभव है? –

+0

क्या आपने इस मुद्दे को हल किया है? –

+0

@ जतिनमालवाल किस मुद्दे पर? –

1

धन्यवाद सामी एंडोनी। मैं अपनी स्थिति के अनुरूप एक मामूली संशोधन के साथ अपने उपनाम ToBeanNestedResultTransformer का उपयोग करने में सक्षम था। मुझे जो मिला वह यह था कि नेस्टेड ट्रांसफॉर्मर उस परिदृश्य का समर्थन नहीं करता है जहां क्षेत्र एक सुपर क्लास में है, इसलिए मैंने इसे कक्षा के वर्ग विरासत पदानुक्रम में गहराई से 10 स्तर तक के क्षेत्रों की तलाश करने के लिए बढ़ाया है:

public Object transformTuple(Object[] tuple, String[] aliases) { 

     ... 


       if (alias.contains(".")) { 
        nestedAliases.add(alias); 

        String[] sp = alias.split("\\."); 
        String fieldName = sp[0]; 
        String aliasName = sp[1]; 

        Class<?> subclass = getDeclaredFieldForClassOrSuperClasses(resultClass, fieldName, 1); 
... 
} 

कहाँ getDeclaredFieldForClassOrSuperClasses() के रूप में परिभाषित किया गया है इस प्रकार है:

private Class<?> getDeclaredFieldForClassOrSuperClasses(Class<?> resultClass, String fieldName, int level) throws NoSuchFieldException{ 
    Class<?> result = null; 
    try { 
     result = resultClass.getDeclaredField(fieldName).getType(); 
    } catch (NoSuchFieldException e) { 
     if (level <= 10){ 
     return getDeclaredFieldForClassOrSuperClasses(
       resultClass.getSuperclass(), fieldName, level++); 
     } else { 
      throw e; 
     } 
    } 
    return result; 
} 
इस नेस्टेड संपत्ति के लिए

मेरे हाइबरनेट प्रक्षेपण इस तरह देखा:

Projections.projectionList().add(Property.forName("metadata.copyright").as("productMetadata.copyright")); 

और वर्ग मैं इस तरह दिखता में पेश कर रहा हूँ:

public class ProductMetadata extends AbstractMetadata { 
... 
} 

public abstract class AbstractMetadata { 
... 
    protected String copyright; 
... 
} 
+0

क्या आपने नेस्टेड ट्रान्सफॉर्मर लिखा था जो 'वनटॉनी (संग्रह)' का समर्थन कर सकता है? –

+0

@ सांगडोल ने इसे लिखा, मैंने इसे बेस क्लास से फ़ील्ड में 10 स्तरों तक गहराई से – whitestryder

-1

के बजाय Data Transfer Object (DTO)
बनाने projectionlist में परिवर्तन नीचे बनाने के लिए और यह आप के लिए काम करेंगे।

ProjectionList projections = Projections.projectionList(); 
    projections.add(Projections.property("person.personID"), "personID"); 
    projections.add(Projections.property("person.wife"), "wife"); 
    projections.add(Projections.property("wife.name")); 

    Criteria criteria = null; 
    criteria = getHandlerSession().createCriteria(Person.class,"person").createAlias("person.wife", "wife"); 
    criterion = Restrictions.eq("wife.age", 19); 
    criteria.add(criterion); 
    criteria.setProjection(projections); 
    criteria.setResultTransformer(Transformers.aliasToBean(Person.class)); 
    return criteria.list(); 
+0

तक प्रोजेक्ट करने में सहायता करने के लिए इसे बढ़ाया है, यह मेरे लिए काम नहीं कर रहा है। –

+0

जो काम नहीं करता –

+0

काम नहीं कर रहा है अलग शब्द है, अपना हाइबरनेट संस्करण और पूर्ण क्वेरी प्रदान करें –

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