jpa2重复使用了guice的entityManager

jpa2 reuses entityManager with guice

我有一个网络应用程序,有一些奇怪的行为,我不能真正把我的手指。 我的问题的核心是在我的休息终点返回的值中存在不一致的行为。 当我启动我的应用程序时,每次我调用此端点时,查询都返回相同的值。 当我更新一个实体时,我的实体经理开始表现得很奇怪。 现在我的查询开始返回不同的结果。 有一次它返回旧值而不是数据库中的值,或者我的结果列表包含代理而不是对象(混合)。 在这里输入图像描述

我已验证我的@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"));
    }
}

我知道这是一个模糊的问题,但有人能帮助我朝着正确的方向发展吗? 这不是我可以提供错误信息的问题。

编辑:我现在指出这个问题。 使用profiler,我查看了guice重用的entitycontext。 这意味着它不会每次执行查询,而是使用现有的实体管理器,每次传递@transactional注释时都应创建该实体管理器。

问题作者:jelle
采纳答案:

我从邮件列表中获得了这个awnser。

Guice perstist有一个非常不寻常的特征,会导致一些问题。 我想你可能只是在打它

当你在一个工作单位之外请求一个实体经理时,guice坚持将暗中启动你的工作单位。 不幸的是,UnitOfWork上的isActive()是私有包。 而且你不能测试一个工作单元是否处于活动状态。

有两种方法明确开始和结束工作单元。 您可以使用UnitOfWork和begin()和end()方法。 另外@Transactional注释开始一个工作单元。 @Transactional只会在它开始时才会结束工作单元。

最好的做法是仅在@Transactional方法中获取实体管理器。

我只能断定@Transaction注释的成熟度级别与春天的不一样。 另一方面,通过提供者获取@Transactional管理器中的实体管理器并不能真正解决这个问题。

由于我们很快就要投入生产,所以我已经回到了春天,这真是一个耻辱,但它是管理我们最后期限的唯一明智的解决方案。

答案作者:jelle

参考更多解答:jpa2 reuses entityManager with guice,转载请保留jpa2重复使用了guice的entityManager

更多:java