同一应用程序中的 JPA/Eclipselink 和 JDBC 连接

Posted

技术标签:

【中文标题】同一应用程序中的 JPA/Eclipselink 和 JDBC 连接【英文标题】:JPA/Eclipselink and JDBC Connections in the same application 【发布时间】:2013-11-14 15:24:54 【问题描述】:

我想在同一个应用程序中通过 JPA/Eclipselink 和 JDBC 连接访问持久层。

问题是,直接使用 JDBC 连接进行的更改不会反映到 JPA EntityManagers,即使我之后打开新创建的 EntityManager。

我正在为 JDBC 连接和 JPA EntityManager 使用 Tomcat 的 JDBC 连接池。

有没有办法处理这种“冲突”?我发现了这个:Disable caching in JPA (eclipselink)。

我也发现了这个:http://wiki.eclipse.org/EclipseLink/Examples/JPA/EMAPI#Getting_a_JDBC_Connection_from_an_EntityManager,但我不喜欢这个想法,因为使用 JDBC-Connections 的代码位于一个单独的库中,根本不应该使用 JPA。

是否有与 JDBC-Connections 和 JPA/Eclipselink-Connections 同样工作的最先进的解决方案?

【问题讨论】:

【参考方案1】:

您是否尝试过禁用共享缓存? JPA 允许两个级别的缓存——在工厂(共享)级别和在 EM 本身内保存托管实体。如果您在 JPA 之外进行更改,则需要考虑这些缓存。使用来自 JPA 的连接无法解决此问题,因为它仍然没有挂钩到 JPA 的缓存。因此,只有在清除 em 或刷新涉及更改的实体时,才能看到 EM 之外的更改。

我会用 http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching 以及 James 在堆栈溢出问题中的回答提供的 http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching 链接作为参考。

在同一个应用程序中使用 JDBC 与在不同应用程序中进行更改基本相同,只是 JPA 应用程序可能对所做的更改有更多的控制和了解,从而允许发生特定的失效或刷新。因此,虽然禁用共享缓存可能是最简单/最快的解决方案,但 EclipseLink 失效和有针对性的刷新可能仍然允许获得缓存的好处。

【讨论】:

【参考方案2】:

我想回答我自己的问题。

就我而言,我有一系列这样的操作:

    使用 JPA EntityManager 使用 JDBC 连接 使用 JPA EntityManager

在上述场景中,可能会在步骤 3 中处理无效数据。

这是一个工作序列:

    使用 JPA EntityManager 关闭EntityManager 使用 JDBC 连接 关闭 JDBC 连接 创建一个新的 JPA EntityManager 刷新所有缓存: em.getEntityManagerFactory().getCache().evictAll(); (1) 使用 JPA EntityManager

在这种特殊的操作序列中(当一个人必须在并发环境中工作时会有所不同),这比禁用整个应用程序的缓存要好。

有关此问题的更一般的答案,请参阅上面的 Chris anwser。

(1)http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching

【讨论】:

@Chris 和其他人:你知道如何在事务中处理这个序列吗? 如果您使用的是 JTA 数据源,那么步骤 1-3 将在同一个事务中,您只需在步骤 1 结束时调用 em.flush 以使其尽早写出更改。如果不在 JTA 中,您将需要确保它们都使用相同的连接以及为所有 3 个步骤启动的事务。可能使用 em 来获取和启动事务,并从 em 获取连接以在步骤 2 中使用,然后重用相同的 em(仍然在步骤 1 结束时刷新)但清除它以便它可以看到步骤 2 的更改

以上是关于同一应用程序中的 JPA/Eclipselink 和 JDBC 连接的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 中的 Spring Data JPA + EclipseLink

JPA - EclipseLink - 如何更改默认模式

Windows 7中的JPA Eclipselink查询解析问题

JPA + EclipseLink + SAP云平台 = 运行在云端的数据库应用

JPA + EclipseLink + SAP云平台 = 运行在云端的数据库应用

JPA/EclipseLink - 计算列