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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4374730/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 16:39:45  来源:igfitidea点击:

How to check if a record exists using JPA

javajpa

提问by Balázs Németh

I want to know whether a given record is present in a database or not. so far I have achieved this by writing a JPA query and the running it by getSingleResult()method. this would throw a NoResultExceptionif the record with the given parameter does not exist. Of course, it's not a must for the record to exist, so it's the normal behaviour sometimes, that's why I asked to myself, is it neccessary to throw an Exception which I have to handle by a catch block? As far as I know the cost of Exception handling is quite big, so I'm not very satisfied with this solution, also, I don't even need the object, I only need to know it's existence in the DB.

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

Is there a better way to check whether an object exist or not? eg. using getResultList()and checking it's size maybe?

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

采纳答案by Aaron Digulla

If you just want to know whether the object exists, send a SELECT COUNTto your database. That will return 0 or 1.

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

The cost of the exception handling isn't that big (unless you do that millions of times during a normal operation), so I wouldn't bother.

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

But the code doesn't really reflect your intention. Since getSingleResult()calls getResultList()internally, it's clearer like so:

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

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

If you query by object id and you have caching enabled, that will become a simple lookup in the cache if the object has already been loaded.

如果您按对象 id 查询并且启用了缓存,那么如果该对象已经被加载,这将成为在缓存中的简单查找。

回答by J?rn Horstmann

If you are searching by primary key you can also use Entitymanger.find(entityClass, primaryKey)which returns nullwhen the entity does not exist.

如果您按主键搜索,您还可以使用Entitymanger.find(entityClass, primaryKey)whichnull在实体不存在时返回。

回答by Radu

Try to avoid loading the entity into the session (getSingleResult()) just to check for it's existence. A count is better here. With the Criteria Query API it would look something like this:

尽量避免将实体加载到会话 ( 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;
}

回答by Halayem Anis

Simply use count(e)in your query, so no NoResultExceptionwill be thrown and you will avoid loading the entity object
So the Java code can be as follow:

只需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 );
}

Hope that helps someone :)

希望对某人有所帮助:)

回答by user738048

here is a generic approach to work with a type Tand an arbitrary IDvalue

这是处理类型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; 
}

回答by Van Tyc

Try this

尝试这个

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