我面对类似于Invalidating JPA EntityManager session描述的一个问题:使用JPA时避免来自数据库的陈旧数据?
问题:让旧数据
我们正在运行JPQL的查询也同时由不同的应用程序更改SQL数据库上。我们使用在Tomcat下运行的JSF + Spring + EclipseLink。
类做JPQL查询是一个单独的Spring bean,并使用注射EntityManager
:
@Component
public class DataRepository{
@PersistenceContext
private EntityManager entityManager;
public List<MyDTO> getStuff(long id) {
String jpqlQuery ="SELECT new MyDTO([...])";
TypedQuery<MyDTO> query = entityManager.createQuery(jpqlQuery,MyDTO.class);
return query.getResultList();
}
[...]
(代码转述)。
问题是此代码没有看到直接在数据库上执行的更改。如果Tomcat实例重新启动,这些更改只会变得可见。
我们已经尝试
我们假设该行为是由相关的EntityManager
一级高速缓存中引起的,如链接的问题进行说明。我们发现了两个解决方案:
- 呼叫
entityManager.clear()
调用createQuery
之前(这是建议的链接的问题) - 注入的
EntityManagerFactor
(使用@PersistenceUnit
),然后创建并关闭新EntityManager
为每个查询
这两种解决方案都能做到我们想要的 - 我们获得新的数据。
问题:
- 是这两种解决方案是否正确?哪一个更好?
- 特别是,我们可以安全地在注入的EntityManager上调用
entityManager.clear()
,或者这会以某种方式影响也使用注入的EntityManager的其他代码(在相同或不同的类中)? - 有没有不同的更好的方法?我们可以以某种方式声明我们想刷新缓存,或者我们想要一个新的
EntityManager
?
我想这一定是一个相当普遍的问题(因为它发生时多个应用程序共享一个数据库),所以我想必须有一个简单的解决方案...
我认为这不是很常见的共享与多个应用程序的数据库?这听起来像你会不断重新加载你的EntityManager而受到严重惩罚。你不能通过服务提供所需的数据吗?或者在应用程序之间使用一些共享缓存? – vertti
@vertti:好点。我没有意识到JPA在使用共享数据库时存在这样的问题。当然,使用服务或类似服务是可能的,但这意味着一个重大变化,而且不太可能发生。 – sleske