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

时间:2010-12-07 08:35:55

标签: java jpa

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

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

6 个答案:

答案 0 :(得分:26)

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

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

但是代码并没有真正反映你的意图。由于getSingleResult()在内部调用getResultList(),因此更清晰:

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

如果按对象ID查询并且启用了缓存,那么如果已经加载了对象,那么它将成为缓存中的简单查找。

答案 1 :(得分:18)

尽量避免将实体加载到会话(getSingleResult())中以检查它是否存在。这里的数量更好。使用Criteria Query 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;
}

答案 2 :(得分:7)

只需在查询中使用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 );
}

希望能帮助某人:)

答案 3 :(得分:4)

如果您按主键搜索,也可以使用Entitymanger.find(entityClass, primaryKey),当实体不存在时,null会返回{{1}}。

答案 4 :(得分:1)

这是使用类型 T 和任意 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; 
}

答案 5 :(得分:0)

尝试

public boolean exists(Object id){
    return getEntityManager().find(entityClass, id)!=null;
}