jpa2使用guice重用entityManager

时间:2014-05-06 19:37:38

标签: java jpa-2.0 guice resteasy guice-persist

我有一个网络应用程序有一些奇怪的行为,我无法真正指责。 我的问题的核心是我的休息端点返回的值存在不一致的行为。 当我启动应用程序时,每次调用此端点时,我的查询都会返回相同的值。当我更新实体时,我的实体管理器开始表现得很奇怪。现在我的查询开始返回不同的结果。有一次它返回旧值而不是数据库中的值,或者我的结果列表包含代理而不是对象(混合)。 enter image description here

我已经验证我的@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注释时都应该创建该实体管理器。

1 个答案:

答案 0 :(得分:1)

我从邮件列表中找到了这个awnser。

  

Guice perstist有一个相当不寻常的特征并导致一些   问题。我想你可能会碰到它

     

当您在工作单元之外请求实体经理时   坚持将隐含地为你启动工作单元。不幸   UnitOfWork上的isActive()是包私有的。你无法测试   如果一个工作单位是活跃的。

     

有两种方法可以明确地启动和结束工作单元。您可以   使用UnitOfWork和方法begin()和end()。还有   @Transactional注释启动一个工作单元。 @Transactional会   当且仅当它开始时,也结束了工作单元。

     

最佳做法是只获取一个实体经理   @Transactional方法。

我只能得出结论,@ Transtion注释与春天的成熟度水平不同。另一方面,通过提供商将实体经理纳入@Transactional经理并不能解决这个问题。

由于我们很快就会投入生产,我已经转回春天,这是一个耻辱,但是唯一明智的解决方案来管理我们的截止日期。