2011-12-14 138 views
10

我需要從表中檢索單行,並且我感興趣什麼方法更好。 一方面getSingleResult是爲檢索單個結果而設計的,但它引發異常。請問這種方法在有關getResultList性能優勢與什麼是更好的:getSingleResult,或getResultList JPA

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

「但它提高了ecxeption。」它有什麼例外呢? (實際上它們都可以引發異常)。我不知道性能(哪一個更高性能,它應該可以忽略不計),但認爲`getSingleResult`使您的代碼更具可讀性。 – 2011-12-14 05:58:14

+0

是的,我同意getSingleResult更具可讀性。我只想知道哪些方法更有效。 – Pilgrim 2011-12-14 06:18:20

回答

9

getSingleResult拋出NonUniqueResultException,如果有多個行。它的目的是在真正獲得單一結果時檢索單個結果。

您所採取的方式很好,JPA旨在正確處理此問題。同時,您無法以任何方式將其與getSingleResult進行比較,因爲它不起作用。

但是,取決於您正在使用的代碼,最好是優化查詢以返回單個結果,如果這就是您想要的 - 那麼您可以致電getSingleResult

+1

但我需要處理notFound異常。這部分代碼需要通過郵件確認碼獲取用戶帳戶實體。我明白,使用getSingleResult更清晰,但我知道異常處理開銷 – Pilgrim 2011-12-14 06:14:06

+0

與`fetch()`結合使用'setMaxResults(1)`可以導致部分初始化的對象。見下面的例子。 – Leukipp 2016-08-30 19:36:08

3

有,我會推薦一種替代方案:

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

對空指針異常,保證只返回1結果。這保障。

15

根據有效的Java由約書亞·布洛克:

使用檢查條件的異常從至極主叫方可以 合理預期的恢復。使用運行時異常來指示 編程錯誤。

信用到源: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

getSingleResult拋出NonUniqueResultException,如果有多個行或沒有任何行。它的目的是在真正獲得單一結果時檢索單個結果。

1

fetch()結合使用setMaxResults(1)可以導致部分初始化的對象。例如,

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()無極限 - 有點不滿意。

相關問題