【问题标题】:Why does 'EntityManager.contains(..)' return false even if an entity is contained in DB?为什么即使实体包含在数据库中,'EntityManager.contains(..)' 也会返回 false?
【发布时间】:2018-08-13 06:58:07
【问题描述】:

我用这个JPA: check whether an entity object has been persisted or not 知道我是坚持还是合并我的实体,它看起来像这样:

if (!getEntityManager().contains(entity)) {
        System.out.println(" PERSIST ");            
    } else {
        System.out.println(" MERGE ");
    }

情况是 - 即使我编辑我的实体 - 它也不会被识别为合并。

这怎么可能以及如何使其发挥作用?

【问题讨论】:

    标签: java jpa entitymanager jpa-2.1


    【解决方案1】:

    根据JPA 2.1 specification(PDF 第 72 页),

    EntityManager 方法 public boolean contains(Object entity) 可以:

    检查实例是否是属于当前持久性上下文的托管实体实例。

    因此,检查不是针对实际数据库,而是针对当前persistence context

    此外,在规范文档的 PDF 第 86 页上,我们发现:

    contains 方法返回true

    • 如果实体已从数据库中检索或已由 getReference 返回,并且被删除或分离

    • 如果实体实例是新的,并且已在实体上调用了persist 方法或已将persist 操作级联到它。

    contains 方法返回false

    • 如果实例分离

    很可能,在执行代码 sn-p 的调用代码时,您有一个 分离 实体状态。因此,对contains(..) 的调用始终计算为false

    作为替代方案,您可以使用

    • public <T> T find(Class<T> entityClass, Object primaryKey)(见第 66 页)
    • public <T> T getReference(Class<T> entityClass, Object primaryKey)(见第 68 页)

    检查底层数据库中是否存在元组。您选择上述哪种方法取决于您的代码/应用程序的上下文。

    希望对你有帮助。

    【讨论】:

    • 感谢您的回答,我认为如果您添加一个关于两个替代答案的示例(如何使用它),它将是有史以来最好的答案。
    • 我找到了一个更好的解决方案,您有兴趣改进您的答案以使其变得更好吗?!?
    • 点赞阅读答案(是我)(如何获取任何 JPA 实体的主键?)[stackoverflow.com/questions/3328813/…
    • 这可能仅特定于某些持久性提供程序,例如 Hibernate 或 Eclipselink,并且可能不适用于纯 JPA 样式。将在接下来的几天内对此进行检查。我认为:也许,这超出了关于contains(..) 的原始问题的范围。
    • 是的,我完全同意你的观点,但我提供给你的答案可以代替 contains(..) 作为替代解决方案
    猜你喜欢
    • 2021-08-15
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    • 2020-10-02
    • 2020-10-12
    • 1970-01-01
    相关资源
    最近更新 更多