如何使用JPA检查记录是否存在

问题描述:

我想知道给定的记录是否存在于数据库中。到目前为止,我已通过编写JPA查询并通过getSingleResult()方法运行它来实现此目的。如果具有给定参数的记录不存在,则会抛出NoResultException。当然,记录不是必须存在的,所以有时候这是正常的行为,这就是为什么我问自己,是否有必要抛出一个我必须通过catch块来处理的异常?据我所知,异常处理的成本相当大,所以我对这个解决方案并不满意,而且我甚至不需要这个对象,我只需要知道它在DB中的存在。如何使用JPA检查记录是否存在

有没有更好的方法来检查一个对象是否存在?例如。使用getResultList()并检查它的大小可能?

+1

好问题,但你应该改变其标题为“如何检查是否存在记录使用JPA”或类似的东西。 – 2010-12-07 12:17:42

+0

感谢您的评论,完成:) – 2010-12-15 14:05:09

+0

更新:存储库存在(id)方法。 repo.exist(id)返回true如果记录存在或者其他错误 – 2017-10-12 16:50:01

如果您只是想知道对象是否存在,请将SELECT COUNT发送到您的数据库。这将返回0或1.

异常处理的成本并不是那么大(除非在正常操作期间执行数百万次),所以我不打扰。

但代码并不真正反映你的意图。由于getSingleResult()呼吁getResultList()在内部,它是像这样清晰的:

public boolean objExists(...) { 
    return getResultList(...).size() == 1; 
} 

如果通过对象ID查询,你必须启用缓存,这将成为高速缓存简单的查找对象是否已经被加载。

+0

哦,你完全正确的选择COUNT解决方案,我忽略了它出于某种原因。但答案的第二部分包含我真正需要的信息,并且非常感谢。 – 2010-12-07 08:46:23

+0

您是否同意如果您想获得查询的第一个结果,并且通常查询不返回任何内容,最好是执行'query.setMaxResults(1)'然后'getResultList()'?这样我们将避免处理异常。 (注意:我在一个叫做MANY次的工作中运行这个)。 – GuilhermeA 2010-12-23 14:50:49

如果您是通过主键进行搜索,也可以使用Entitymanger.find(entityClass, primaryKey),当实体不存在时返回null

尝试避免将实体加载到会话(getSingleResult())中以检查其是否存在。点数在这里更好。随着条件查询API它会是这个样子:

public <E extends AbstractEntity> boolean exists(final Class<E> entityClass, final int id) { 
    final EntityManager em = getEntityManager(); 
    final CriteriaBuilder cb = em.getCriteriaBuilder(); 

    final CriteriaQuery<Long> cq = cb.createQuery(Long.class); 
    final Root<E> from = cq.from(entityClass); 

    cq.select(cb.count(from)); 
    cq.where(cb.equal(from.get(AbstractEntity_.id), id)); 

    final TypedQuery<Long> tq = em.createQuery(cq); 
    return tq.getSingleResult() > 0; 
} 

在查询只需使用count(e),所以没有NoResultException会被抛出,你会避免加载实体对象
所以Java代码可以如下:

public boolean isRecordExist() { 
    String query = "select count(e) from YOUR_ENTITY e where ...."; 
    // you will always get a single result 
    Long count = (Long) entityManager.createQuery(query).getSingleResult(); 
    return ((count.equals(0L)) ? false : true); 
} 

希望帮助别人:)

这里是一个类型牛逼和工作的通用做法任意ID

public boolean exists(Object key) { 
    EntityManager entityManager = getEntityManager(); 
    Metamodel metamodel = entityManager.getMetamodel(); 
    EntityType<T> entity = metamodel.entity(entityClass); 
    SingularAttribute<T, ? extends Object> declaredId = entity.getDeclaredId(key.getClass()); 
    CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 
    javax.persistence.criteria.CriteriaQuery<T> cq = cb.createQuery(entityClass); 
    Root<T> from = cq.from(entityClass); 
    Predicate condition = cb.equal(from.get(declaredId), key); 
    cq.where(condition); 
    TypedQuery<T> q = entityManager.createQuery(cq); 
    return q.getResultList().size() > 0; 
}