我需要从表中检索单行,我感兴趣的是哪种方法更好。
一方面getSingleResult
用于检索单个结果,但它会引发异常。此方法是否与getResultList
与
query.setFirstResult(0);
query.setMaxResults(1);
答案 0 :(得分:18)
Joshua Bloch撰写的Effective 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 :(得分:10)
getSingleResult
会抛出NonUniqueResultException
。它设计用于在真正有单个结果时检索单个结果。
你做的方式很好,JPA旨在正确处理这个问题。同时,您无法以任何方式将其与getSingleResult
进行比较,因为它无效。
但是,依赖于您正在处理的代码,最好优化查询以返回单个结果,如果这就是您想要的全部 - 那么您只需调用getSingleResult
。
答案 2 :(得分:3)
我建议有另一种选择:
Query query = em.createQuery("your query");
List<Element> elementList = query.getResultList();
return CollectionUtils.isEmpty(elementList ) ? null : elementList.get(0);
这可以防止Null Pointer Exception,保证只返回1个结果。
答案 3 :(得分:1)
如果有多行或没有任何行,则getSingleResult会抛出NonUniqueResultException。它设计用于在真正有单个结果时检索单个结果。
答案 4 :(得分: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()
没有限制 - 有点不满意。