2012-04-24 10 views
7

के बजाय शून्य देता है आमतौर पर मैं "रिक्त" ऑब्जेक्ट को वापस करने के लिए NoResultException के साथ काम करता हूं, उदा। एक खाली त्रुटि सूची या नया BigInteger ("0"), अगर मुझे TypedQuery से कोई परिणाम नहीं मिलता है। अब यह पता चला कि यह कभी-कभी काम नहीं करता है। अचानक मिलें SingleResult() NoResultException के कारण नल लौटाता है, और मुझे समझ में नहीं आता क्यों। इस उदाहरण देखो:जेपीए: TypedQuery कभी-कभी NoResultException

public BigInteger pointsSumByAccountId(long accountId) 
{ 
    try 
    { 
     TypedQuery<BigInteger> pointsQuery = entityManager.createNamedQuery(Points.SumByAccountId, BigInteger.class); 
     pointsQuery.setParameter(Points.AccountIdParameter, accountId); 

     return pointsQuery.getSingleResult(); 
    } 
    catch (NoResultException e) 
    { 
     return new BigInteger("0"); 
    } 
} 

इकाई की महत्वपूर्ण हिस्सा ...

@NamedQueries({@NamedQuery(name = "Points.sumByAccountId", query = "select sum(p.value) from Points p where p.validFrom <= current_timestamp() and p.validThru >= current_timestamp() and p.account.id = :accountId")}) 
public class Points 
{ 
    private static final long serialVersionUID = -15545239875670390L; 

    public static final String SumByAccountId = Points.class.getSimpleName() + ".sumByAccountId"; 
    public static final String AccountIdParameter = "accountId"; 
. 
. 
. 

अगर मैं एक ACCOUNTID जो कोई परिणाम का कारण बनता है का उपयोग करें, मैं NoResultException के बजाय अशक्त मिलता है। कोई विचार क्यों ऐसा है? TypedQuery की भी जावाडोक कहना है कि वह NoResultException वापस जाने के लिए है:

/** 
* Execute a SELECT query that returns a single result. 
* 
* @return the result 
* 
* @throws NoResultException if there is no result 
* @throws NonUniqueResultException if more than one result 
* @throws IllegalStateException if called for a Java 
* Persistence query language UPDATE or DELETE statement 
* @throws QueryTimeoutException if the query execution exceeds 
* the query timeout value set and only the statement is 
* rolled back 
* @throws TransactionRequiredException if a lock mode has 
* been set and there is no transaction 
* @throws PessimisticLockException if pessimistic locking 
* fails and the transaction is rolled back 
* @throws LockTimeoutException if pessimistic locking 
* fails and only the statement is rolled back 
* @throws PersistenceException if the query execution exceeds 
* the query timeout value set and the transaction 
* is rolled back 
*/ 
X getSingleResult(); 

उत्तर

19

यह मेरे लिए एक सही व्यवहार की तरह दिखता है। जब कोई भी पंक्ति लौटा दिए जाते हैं

NoResultException फेंक दिया है, लेकिन आपके मामले में मूल्य sum रिटर्न ठीक एक null साथ पंक्ति। जेपीए 2.0 विशिष्टता से:

तो योग, औसत, मैक्स, या मिन प्रयोग किया जाता है, और कोई मान समेकित फ़ंक्शन लागू किया जा सकता है जो करने के लिए देखते हैं, समेकित फ़ंक्शन का परिणाम शून्य है।

आप null के बजाय 0 प्राप्त करना चाहते हैं, coalesce का उपयोग करें:

select coalesce(sum(p.value), 0) ... 
+1

ट्रिकी, लेकिन है कि यह बताता है, धन्यवाद। – Bevor

+0

मैं समझता हूं कि एक खाली सेट का AVG, MAX और MIN अपरिभाषित है, लेकिन खाली सेट का SUM 0 है। मुझे आश्चर्य है कि वे इसके लिए क्यों विफल हो जाते हैं। – VinyJones

+0

एसयूएम, एवीजी, MAX, या MIN एक गैर-खाली सेट के लिए भी 0 हो सकते हैं। रिटर्निंग नल खाली सेट की पुष्टि करता है। – Ritesh