2011-12-14 9 views
10

मुझे तालिका से एकल पंक्ति पुनर्प्राप्त करने की आवश्यकता है, और मुझे रूचि है कि कौन सा दृष्टिकोण बेहतर है। एक तरफ getSingleResult एकल परिणाम पुनर्प्राप्त करने के लिए डिज़ाइन किया गया है, लेकिन यह अपवाद उठाता है। करता है इस विधिबेहतर क्या है: getSingleResult, या getResultList JPA

query.setFirstResult(0); 
query.setMaxResults(1); 
+0

"लेकिन यह ecxeption को जन्म देती है।" यह क्या अपवाद उठा रहा है? (वास्तव में उनमें से दोनों अपवाद बढ़ा सकते हैं)। मैं प्रदर्शन के बारे में पता नहीं है (जो भी अधिक performant है, यह नगण्य होना चाहिए), लेकिन लगता है कि 'getSingleResult' अपने कोड अधिक पठनीय बनाता है। –

+0

हां, मैं मानता हूं कि getSingleResult अधिक पढ़ने योग्य है। मैं सिर्फ यह जानना चाहता हूं कि कौन सा अपमान अधिक कुशल है। – Pilgrim

उत्तर

9

getSingleResult साथ getResultList से संबंधित प्रदर्शन में लाभ है NonUniqueResultException फेंकता है, अगर वहाँ कई पंक्तियों कर रहे हैं। यह वास्तव में एक परिणाम होने पर एकल परिणाम पुनर्प्राप्त करने के लिए डिज़ाइन किया गया है।

तरह से तुमने किया था ठीक है और जेपीए इस ठीक से संभाल बनाया गया है। उसी समय, आप इसे getSingleResult के विरुद्ध किसी भी तरह से तुलना नहीं कर सकते, क्योंकि यह काम नहीं करेगा।

हालांकि, आप जिस कोड पर काम कर रहे हैं उस पर निर्भर करते हैं, यदि आप जो भी चाहते हैं, उसे वापस करने के लिए क्वेरी को परिष्कृत करना हमेशा बेहतर होता है - तो आप केवल getSingleResult पर कॉल कर सकते हैं।

Query query = em.createQuery("your query"); 
List<Element> elementList = query.getResultList(); 
return CollectionUtils.isEmpty(elementList) ? null : elementList.get(0); 

नल पॉइंटर एक्सेप्शन, गारंटी केवल 1 परिणाम दिया जाता है के खिलाफ यह सुरक्षा उपायों:

+1

लेकिन मुझे फाउंड अपवाद को संभालने की आवश्यकता नहीं है। कोड के इस भाग को ईमेल पुष्टिकरण कोड द्वारा उपयोगकर्ता खाता इकाई प्राप्त करने की आवश्यकता है। मैं समझता हूं कि ज्यादा इस बात के लिए getSingleResult उपयोग करने के लिए स्पष्ट है, लेकिन मैं 'लाने()' 'setMaxResults (1) के उपयोग के साथ भूमि के ऊपर – Pilgrim

+0

संयोजन में से निपटने के अपवाद के बारे में पता कर रहा हूँ' एक आंशिक रूप से initialised वस्तुओं हो सकता है। उदाहरण के लिए नीचे देखें। – Leukipp

3

एक वैकल्पिक जो मैं सिफारिश करेंगे नहीं है।

+1

क्यों सिर्फ elementList.isEmpty() के बजाय संग्रह उपयोग करता है? – Tomasz

+0

@Tomasz का उपयोग करते हुए [http://commons.apache.org/collections/apidocs/org/apache/commons/collections/CollectionUtils.html#isEmpty(java.util.Collection)], isEmpty() सच है, तो सूची लौटाता है शून्य या खाली है।CollectionUtils इसे लिखने के बजाय आसान कोड पठनीयता प्रदान करता है: '(elementList! = Null) &&! ElementList.isEmpty()। –

+1

आप किस प्रदाता का उपयोग कर रहे हैं? ग्रहण लिंक [EJBQueryImpl.getResultList()] (http://grepcode.com/file/maven.glassfish.org/content/repositories/eclipselink/org.eclipse.persistence/org.eclipse.persistence.jpa/2.1.1/org /eclipse/persistence/internal/jpa/EJBQueryImpl.java#EJBQueryImpl.getResultList%28%29) कभी भी शून्य – Tomasz

15

प्रभावी जावा यहोशू बलोच द्वारा के अनुसार:

उपयोग फोन करने वाले जो से जाँच की स्थितियों के लिए अपवाद यथोचित ठीक होने की उम्मीद की जा सकती है। प्रोग्रामिंग त्रुटियों को इंगित करने के लिए रनटाइम अपवादों का उपयोग करें। स्रोत के लिए

क्रेडिट: Why you should never use getSingleResult() in JPA

@Entity 
@NamedQuery(name = "Country.findByName", 
      query = "SELECT c FROM Country c WHERE c.name = :name" 
public class Country { 
    @PersistenceContext 
    transient EntityManager entityManager; 

    public static Country findByName(String name) { 
     List<Country> results = entityManager 
      .createNamedQuery("Country.findByName", Country.class) 
      .setParameter("name", name).getResultList(); 
     return results.isEmpty() ? null : results.get(0); 
    } 
} 
+1

बहुत बहुत धन्यवाद, बहुत उचित स्पष्टीकरण – Pilgrim

+0

जावा में बहुत कम निरपेक्ष हैं और यह आलेख उपदेश सभी उपयोग मामलों के लिए मान्य नहीं है। उदाहरण के लिए, क्वेरी को कुछ बिज़ आवश्यकता को पूरा करने के लिए हमेशा एक पंक्ति वापस करनी चाहिए ताकि चक्रों को गिनती की जांच करने के लिए परिणामों की एक सूची को मार्शल करने के लिए खर्च किया जाए ताकि यह देखने के लिए कि बिज़ की स्थिति का उल्लंघन किया गया था या नहीं, जब आप getSingleResult को कॉल कर सकते हैं और NoResultException/NoUniqueResultException अपवादों को पकड़ सकते हैं और उचित कार्रवाई करें? इसका कम कोड और यह असाधारण बिज़ तर्क स्थितियों को लागू करने के लिए अपवादों का उपयोग करता है। – NBW

+1

@NBW संक्षिप्त उत्तर क्योंकि अपवाद हैंडलिंग अधिक संसाधन उपभोग करने वाला है और आमतौर पर thsi मामले में एक विरोधी पैटर्न माना जाता है http://programmers.stackexchange.com/questions/107723/arguments-for-or-against-using-try-catch- as-logical-operators http://programmers.stackexchange.com/questions/189222/are-exceptions-as-control-flow-cononsidered-a-serious-antipattern-if-so- क्यों http://c2.com/ cgi/wiki? DontUseExceptionsForFlowControl – Tomasz

1

getSingleResult फेंकता NonUniqueResultException एक से अधिक पंक्तियों या कोई समस्त पंक्तियां हैं। यह वास्तव में एक परिणाम होने पर एकल परिणाम पुनर्प्राप्त करने के लिए डिज़ाइन किया गया है।

1

fetch() के साथ संयोजन में setMaxResults(1) के उपयोग एक आंशिक रूप से initialised वस्तुओं हो सकता है। एक सा नाकाफी - उदाहरण के लिए,

CriteriaQuery<Individual> query = cb.createQuery(Individual.class); 
Root<Individual> root = query.from(Individual.class); 
root.fetch(Individual_.contacts); 

query.where(cb.equal(root.get(Individual_.id), id)); 

Individual i = em.createQuery(query) 
    .setMaxResults(1) // assertion fails if individual has 2 contacts 
    .getResultList() 
    .get(0); 
assertEquals(2, i.getContacts().size()); 

तो, मैं getResultList() सीमा के बिना उपयोग कर रहा हूँ।

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