【发布时间】:2014-05-06 19:37:38
【问题描述】:
我有一个 Web 应用程序有一些奇怪的行为,我无法真正解决。 我的问题的核心是我的休息端点返回的值存在不一致的行为。 当我启动我的应用程序时,每次调用此端点时,我的查询都会返回相同的值。当我更新一个实体时,我的实体管理器开始表现得很奇怪。现在我的查询开始返回不同的结果。有一次它返回旧值而不是数据库中的值,或者我的结果列表包含代理而不是对象(混合)。
我已验证我的 @transaction 方法放置正确,并且在我的调试堆栈中,我看到了事务拦截器,并且根据对后端的请求创建了实体管理器(因此没有 guice 持久性过滤器)
我的感觉表明问题出在会话上下文中。我有一种感觉(但我无法真正理解)它在多个请求上重用了我的持久性上下文。
我已经将一些框架放在一起以使这一切正常工作。我使用 resteasy 作为 jax-rs 实现者。 guice (4.0beta4) 作为 cdi 实现者,hibernate 作为 jpa 实现者。 因为我们在注入 entitymanager 时需要使用提供程序(因为每个事务都会创建 entitymanager),所以我将其包装在 EntityManagerProxy 中。该类实现了EntityManager接口并将所有方法委托给provider.get().method()。
public class EntityManagerProxy implements EntityManager {
private final Provider<EntityManager> entityManagerProvider;
@Inject
public EntityManagerProxy(final Provider<EntityManager> entityManagerProvider) {
this.entityManagerProvider = entityManagerProvider;
}
private EntityManager getEntityManager() {
return entityManagerProvider.get();
}
@Override
public void persist(final Object entity) {
getEntityManager().persist(entity);
}
}
我的 guice 模块是这样的
public class OptiWEEEModule extends ServletModule implements Module {
@Override
protected void configureServlets() {
super.configureServlets();
bind(EntityManagerProxy.class);
// JPA
install(new JpaPersistModule("myPU"));
}
}
我知道这是一个模糊的问题,但有人可以帮助我朝着正确的方向前进吗?这不是我可以提供错误消息的真正问题。
编辑:我现在指出了问题所在。使用探查器,我查看了实体上下文被 guice 重用。这意味着它不是每次都执行查询,而是使用现有的实体管理器,应该在每次传递@transactional 注释时创建。
【问题讨论】:
-
我刚刚从 guice 4beta4 降级到 guice 3 并且发生了同样的错误。
-
@Transactional的想法是你得到一个新的事务,而不是一个新的 EntityManager。后者也可以处理其中的几个。您没有显示代理的“更新”部分,也没有显示 Web 服务,因此很难说到底是什么导致了您的问题。 -
我实际上深入研究了这个问题。不是更新部分破坏了我的应用程序,而是在每个线程上重用了实体管理器。我想我正在创建一个包含我的 entitymanager 的单身人士。我的 entitymanagerproxy 会导致这种情况吗?这是我遵循的策略code.google.com/p/google-guice/wiki/…
-
This question 听起来很相似。
-
@mabi 这个问题确实很相似,但我已经在每个点都注入了一个提供程序
标签: java jpa-2.0 guice resteasy guice-persist