2012-10-22 12 views
10

अगर मेरे सूची खाली है, मैं निम्नलिखित त्रुटि मिलती है:हाइबरनेट प्रतिबंध यदि कोई त्रुटि सूची खाली है

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' 

नीचे मेरी हाइबरनेट संबंधित विधि है:

@Override 
    public List<SomeThing> findByIds(List<Integer> someIds) { 
     return sessionFactory.getCurrentSession().createCriteria(SomeClass.class) 
       .add(Restrictions.in("id", someIds)) 
       .list(); 
    } 

मुझे क्या करना चाहिए इस त्रुटि के खिलाफ सुरक्षा के लिए करते हैं?

मैं जानता हूँ कि मैं शॉर्ट सर्किट कॉल और की तरह एक खाली सूची लौट सकता है:

if(someIds == null || someIds.size() == 0) { 
    return new List<SomeThing>(); 
} 

लेकिन वहाँ यह करने के लिए एक और अधिक सुरुचिपूर्ण तरीका है?

उत्तर

11

नहीं। यदि आप in खंड के लिए खाली पैरामीटर के साथ क्वेरी निष्पादित करते हैं, तो यह असफल हो जाएगा (आप इसे सादे एसक्यूएल चलाकर सत्यापित कर सकते हैं)। इनपुट पैरामीटर शून्य/खाली होने पर क्वेरी निष्पादित करने के लिए बेहतर नहीं है। (

@Override 
public List<SomeThing> findByIds(List<Integer> someIds) { 
    List<Something> result = null; //you may initialize with empty list 
    if(someIds != null || !someIds.isEmpty() { 
     result = sessionFactory.getCurrentSession().createCriteria(SomeClass.class) 
      .add(Restrictions.in("id", someIds)) 
      .list(); 
    } 
    return result; 
} 
2

यह, ज्यादातर @Yogendra सिंह के जवाब पर आधार है एक मोड़ के साथ यह अधिक ग्रहणीय बनाने के लिए:

केवल बात मैं सलाह कर सकते हैं के रूप में isEmpty() समारोह और if बयान में != null और थोड़ा पुनर्गठन उपयोग करने के लिए है एकाधिक वैकल्पिक तर्क की सामान्य रूप से देखी गई स्थिति के लिए)

मानदंड API का उद्देश्य आपको प्रोग्राम को अपनी क्वेरी लिखना है। इस तरह की गतिशील सुविधा आपके कोड में संभालने की उम्मीद है।

आम तौर पर हम इस से वैकल्पिक मापदंड बनाने:

@Override 
public List<SomeThing> findBySearchParams(SearchParam searchParam) { 
    // create criteria with mandatory search criteria 
    Criteria criteria = sessionFactory.getCurrentSession() 
          .createCriteria(SomeClass.class); 
          .add(Restriction("someField", searchParam.getSomeField())); 


    // add "id" only if "someId" contains value 
    if(searchParam.getSomeIds() != null && !searchParam.getSomeIds().empty()) { 
     criteria.add(Restrictions.in("id", searchParam.getSomeIds())); 
    } 

    // add "anotherField" only if "anOptionalField" is not null 
    if(searchParam.getAnOptionalField() != null) { 
     criteria.add(Restrictions.in("anotherField", searchParam.getAnOptionalField())); 
    } 

    return criteria.list(); 
} 

संपादित करें: अपने आप को बनाने के लिए

हालांकि हाइबरनेट नहीं है (अभी तक) के लिए एक और अधिक सुरुचिपूर्ण तरीका प्रदान करते हैं, आप कुछ लिख सकते हैं यह अधिक सुरुचिपूर्ण दिखता है:

class SmartCriteriaBuilder { 
    private Criteria criteria; 
    SmartCriteriaBuilder (Criteria criteria) { this.criteria = criteria;} 

    SmartCriteriaBuilder in(String field, Collection values) { 
    if (!empty(values)) { 
     this.criteria.add(Restrictions.in(field,values)); 
    } 
    } 
    // all other kind of restrictions .... 

    Criteria toCriteria() { 
    return this.criteria; 
    } 
} 

फिर आप कुछ स्मार्ट दिख सकते हैं:

SmartCriteriaBuilder criteriaBuilder = 
    new SmartCriteriaBuilder(sessionFactory.getCurrentSession().createCriteria()); 

criteriaBuilder .in("someField", listPossiblyNullOrEmpty); 


return criteriaBuilder .toCriteria().list();  
11

मैं कहूंगा कि हाइबरनेट को इस समस्या को ठीक करने और सार्थक संदेश देने की आवश्यकता है।

मुझे लगता है कि खाली/शून्य सूची की जांच करने के लिए प्रदाता/हाइबरनेट की इसकी ज़िम्मेदारी है।

कोई कारण कल्पना कर सकता है, यह कहां बना सकता है, जहां आईडी में कुछ आईडी(), कहीं कहीं org.hibernate.loader.criteria.CriteriaQueryTranslator या इसी तरह .. लेकिन क्योंकि यहां सूची खाली है, यह होगा अपवाद फेंकना लेकिन उन्होंने पहले से ही क्वेरी बनाई है (और अपवाद/खाली सूची के कारण पूरा नहीं हो सका।

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