【问题标题】:Check if JPA entity exists without loading it检查 JPA 实体是否存在而不加载它
【发布时间】:2015-05-17 20:06:45
【问题描述】:

问题来了。

我们有一个服务器端点,它接收来自客户端的反馈。以多部分/基于表单的格式收到的反馈,带有字段:

ProductId - product identifier
Message - feedback message
Log_file - attached log file
Screenshot - attached screenshot file

服务器代码首先检查具有给定 ID 的产品是否存在,如果不存在 - 关闭连接而不接收任何附加文件。

我们使用 Eclipselink JPA 来存储产品对象。

如何在不从底层数据库加载的情况下检查具有给定 id 的产品是否存在?

【问题讨论】:

    标签: java jpa persistence eclipselink


    【解决方案1】:

    您可以使用count 来查看是否会返回任何具有该id 的行。

    em.createQuery(
        "SELECT COUNT(b.productId) 
        FROM Products b WHERE b.productId=:productId"
    );
    

    如果 count < 1 没有具有该 ID 的产品。 否则存在具有该 ID 的产品。

    【讨论】:

    • 当您只需要检查是否有任何符合条件的记录时,计数只是不必要的,我们可以只选择一个常量,例如SELECT 1 FROM Products b WHERE b.productId=:productId
    • @aathif 不,不一定。通过.getSingleResult() 检索您的结果,您要确保始终检索结果。 SELECT 1 不会给出任何结果,以防数据库找不到具有该 ID 的任何记录。你会遇到javax.persistence.NoResultException: getSingleResult() did not retrieve any entities。当然,您可以改为处理此异常 - 但这是干净的代码吗?
    【解决方案2】:

    您到底想避免什么? JPA 允许延迟加载实体中几乎每个字段,因此您返回的内容可能会被加载,也可能不会被加载。如果实体存在,一个简单的 EntityManager.find 操作将从缓存中检索实体,如果不存在,则检查数据库,因此对于大多数情况这可能就足够了。如果它进入数据库,它将构建一个实例并将其放入缓存中,但该实例将仅包含急切映射。

    否则,您可以使用返回数据而不是实体实例的任何 JPA 查询来避免加载,但这需要数据库命中。上面的计数选项是一种方法,但简单的“从员工 e 中选择 e.id,其中 e.id =:empId”也可以。

    【讨论】:

    • 谢谢!我们需要尽量减少请求验证开销。
    猜你喜欢
    • 1970-01-01
    • 2012-05-08
    • 2021-04-10
    • 2017-05-23
    • 1970-01-01
    • 1970-01-01
    • 2013-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多