【发布时间】:2013-01-07 15:45:16
【问题描述】:
我面临的问题类似于Invalidating JPA EntityManager session 中描述的问题:
问题:获取过时的数据
我们正在 SQL 数据库上运行 JPQL 查询,该数据库也被不同的应用程序同时更改。我们使用的是在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 关联的一级缓存引起的,如链接问题中所述。我们找到了两个解决方案:
- 在调用
createQuery之前调用entityManager.clear()(链接问题中建议这样做) - 注入一个
EntityManagerFactor(使用@PersistenceUnit),然后为每个查询创建并关闭一个新的EntityManager
两种解决方案都能满足我们的需求 - 我们获得了新数据。
问题:
- 这两个解决方案是否正确?哪个更好?
- 特别是,我们能否安全地在注入的 EntityManager 上调用
entityManager.clear(),或者这会以某种方式影响也使用注入的 EntityManager(在同一类或不同类中)的其他代码? - 有其他更好的方法吗?我们能否以某种方式声明我们想要刷新缓存,或者我们想要一个新的
EntityManager?
我认为这一定是一个相当普遍的问题(每当多个应用程序共享一个数据库时都会发生),所以我认为必须有一个简单的解决方案......
【问题讨论】:
-
我认为与多个应用程序共享一个数据库不是很常见?听起来你会因为不断地重新加载你的 EntityManager 而受到严厉的惩罚。您不能通过服务来提供所需的数据吗?或者在应用程序之间使用一些共享缓存?
-
@vertti:好点子。我没有意识到 JPA 在使用共享数据库时会出现这样的问题。当然,使用服务或类似服务是可能的,但这意味着重大变化,而且不太可能发生。
标签: database spring caching jpa eclipselink