2010-04-29 11 views
6

मुझे इकाई ऑब्जेक्ट का पालन करना हैहाइबरनेट मानदंड API - एक मानदंड जोड़ना: स्ट्रिंग संग्रह में होना चाहिए

 
 
@Entity 
public class Foobar { 
    ... 
    private List<String> uuids; 
    ... 
} 
 

अब मैं एक मानदंड क्वेरी बनाना चाहता हूं जो सभी Foobar pojos लाएगा जिनकी यूआईआईडी सूची में स्ट्रिंग "abc123" है, मुझे यकीन नहीं है कि कैसे बनाना है उचित मानदंड

उत्तर

7

मैं आपको लगता है कि जेपीए 2.0 लागू करता हाइबरनेट के एक संस्करण का उपयोग कर रहे मान। यहां एक जेपीए 2.0 समाधान है जो किसी भी अनुरूप कार्यान्वयन के साथ काम करना चाहिए।

कृपया जेपीए के @ElementCollection एनोटेशन के साथ uuids एनोटेट करें। कुछ अन्य उत्तर टिप्पणियों में उल्लिखित हाइबरनेट के @CollectionOfElements का उपयोग न करें। उत्तरार्द्ध समकक्ष कार्यक्षमता है लेकिन being deprecated है।

Foobar.java इस तरह लगभग दिखेगा:

@Entity 
public class Foobar implements Serializable { 

    // You might have some other id 
    @Id 
    private Long id; 

    @ElementCollection 
    private List<String> uuids; 

    // Getters/Setters, serialVersionUID, ... 

} 

यहाँ कैसे आप एक CriteriaQuery निर्माण कर सकते हैं सभी Foobar रों जिसका uuids "abc123" शामिल चयन करने के लिए है।

public void getFoobars() { 
{ 
    EntityManager em = ... // EM by injection, EntityManagerFactory, whatever 

    CriteriaBuilder b = em.getCriteriaBuilder(); 
    CriteriaQuery<Foobar> cq = b.createQuery(Foobar.class); 
    Root<Foobar> foobar = cq.from(Foobar.class); 

    TypedQuery<Foobar> q = em.createQuery(
      cq.select(foobar) 
       .where(b.isMember("abc123", foobar.<List<String>>get("uuids")))); 

    for (Foobar f : q.getResultList()) { 
     // Do stuff with f, which will have "abc123" in uuids 
    } 
} 

मैंने इसके साथ खेलने के दौरान एक आत्मनिर्भर प्रमाण-अवधारणा कार्यक्रम बनाया। मैं इसे अभी बाहर नहीं दबा सकता। कृपया टिप्पणी करें कि क्या आप पीओसी को जिथब पर धक्का देना चाहते हैं।

+0

हाइबरनेट 3.6.7-फ़ाइनल के साथ प्रयास किया और काम नहीं करता (यह हाइबरनेट में एक बग प्रतीत होता है)। – greuze

-2

शुरुआत के लिए, मुझे नहीं लगता कि हाइबरनेट List<String> मानचित्र कर सकता है। हालांकि, यह अन्य इकाइयों की एक सूची को मैप कर सकता है।

तो अपने कोड कुछ इस तरह था, तो:

@Entity 
public class Foobar { 

    private List<EntityObject> uuids; 
    ... 
} 

और EntityObject एक String -property str कहा जाता है, मापदंड ऐसा दिखाई दे सकता:

List<Foobar> returns = (List<Foobar>) session 
       .createCriteria.(Foobar.class, "foobars") 
       .createAlias("foobars.uuids", "uuids") 
        .add(Restrictions.like("uuids.str", "%abc123%")) 
       .list(); 
+1

स्ट्रिंग्स की सूची का उपयोग करने में कोई समस्या नहीं है, बस इसे @ कोलेक्शनऑफमेंट्स के साथ एनोटेट करें। आपके समाधान के लिए मुझे एक अतिरिक्त इकाई वर्ग बनाने की आवश्यकता है, जो कि मैं इस विशिष्ट प्रश्न से बचने की उम्मीद कर रहा था। –

1

आप किसी क्वेरी इस्तेमाल कर सकते हैं जैसा कि नीचे दिए गए उदाहरण में है या आप इसे NamedQuery में परिवर्तित कर सकते हैं। दुर्भाग्य से मानदंड के साथ ऐसा करने का कोई तरीका प्रतीत नहीं होता है।

List<Foobar> result = session 
    .createQuery("from Foobar f join f.uuids u where u =: mytest") 
    .setString("mytest", "acb123") 
    .list(); 
1

जो आप पूछ रहे हैं वह हाइबरनेट द्वारा बॉक्स से बाहर समर्थित नहीं है। http://opensource.atlassian.com/projects/hibernate/browse/HHH-869

देखें यहाँ एक वैकल्पिक हल jira टिकट में उपलब्ध है:

entityCriteria.add(Restrictions.sqlRestriction(
    "fooAlias.id in (select e.id from foobar_table e, values_table v" + 
    " where e.id = v.entity_id and v.field = ?)", "abc123"), Hibernate.String)) ; 
2

मुझे यह पोस्ट एक साल पहले मिला है, और मैंने यह तरीका बनाया है, अगर यह किसी भी समस्या के साथ किसी को भी मदद कर सकता है तो मेरे पास कुछ घंटों पहले था।

Public List<EntityObject> getHasString(String string) { 
     return getSession().createCriteria(EntityObject.class) 
           .add(Restriction.like("property-name", string, MatchMode.ANYWHERE).ignoreCase(); 
          .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) 
          .list(); 

स्ट्रिंग के समूह के साथ भी बनाया गया।

public List<EntityObject> getByStringList(String[] tab) { 
     Criterion c = Restrictions.like("property-name", tab[tab.length-1], MatchMode.ANYWHERE).ignoreCase(); 
     if(tab.length > 1) { 
      for(int i=tab.length-2; i >= 0 ; i--) { 
       c = Restrictions.or(Restrictions.like("property-name",tab[i], MatchMode.ANYWHERE).ignoreCase(), c); 
      } 
     } 
     return getSession().createCriteria(EntityObject.class) 
           .add(c) 
          .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) 
          .list(); 
    } 

यह "या" कथन के साथ काम करता है, लेकिन आसानी से "और" कथन द्वारा प्रतिस्थापित किया जा सकता है।

0

jira से sqlRestriction http://opensource.atlassian.com/projects/hibernate/browse/HHH-869 साथ समाधान के बाद से मैं भारी मापदंड एपीआई का उपयोग मेरे लिए जाने के लिए सबसे अच्छा तरीका है लग रहा था। मैं थियरी के कोड को संपादित करना पड़ा तो यह मेरे मामले में काम किया

मॉडल:

@Entity 
public class PlatformData 
{ 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long iID; 

    private List<String> iPlatformAbilities = new ArrayList<String>(); 
} 

मानदंड फोन:

tCriteria.add(Restrictions.sqlRestriction(
     "{alias}.id in (select e.id from platformData e, platformdata_platformabilities v" 
      + " where e.id = v.platformdata_id and v.element = ?)", aPlatformAbility.toString(), 
     Hibernate.STRING)); 
3

मैं जानता हूँ कि इस पुराने सवाल है, लेकिन मैं तो बस इस मुद्दे का सामना करना पड़ा और समाधान मिला

यदि आप हाइबरनेट मानदंड का उपयोग करना चाहते हैं तो आप अपने uuids संग्रह में शामिल हो सकते हैं और तत्वों से मेल खाने के लिए अपनी संपत्ति elements का उपयोग कर सकते हैं। बस इसी तरह:

session.createCriteria(Foobar.class) 
    .createAlias("uuids", "uuids") 
    .add(Restrictions.eq("uuids.elements", "MyUUID")) 
    .list() 
+1

आप निरंतर 'CollectionPropertyNames.COLLECTION_ELEMENTS'" तत्वों "के बजाय भी उपयोग कर सकते हैं। –

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