同一应用程序中的 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
Windows 7中的JPA Eclipselink查询解析问题
JPA + EclipseLink + SAP云平台 = 运行在云端的数据库应用