java - Guice 在多线程应用程序中注入(inject) EntityManager

标签 java jpa guice

我正在使用 Java SE 7 开发桌面应用程序。该应用程序使用多个线程,并且在创建的每个线程中注入(inject)一个 DAO 类以获取对我的数据库的访问权限。作为持久层,我使用 EclipseLink 和 JPA。使用构造函数注入(inject)将 EntityManager 注入(inject)到我的 DAO 类中,并且由于它不是线程安全的,因此我采用了使用 Provder 的方法,如下所示:

public PluginInstanceJpaController implements IPluginInstanceDao {

    private EntityManager em;

    @Injected
    public PluginInstanceJpaController(Provider<EntityManager> emp) {
        this.em = emp.get();
    }

    @Transactional 
    public void create(PluginInstance foo) throws Exception {
        em.persist(foo);
    }
}

但是,每个 DAO 中都注入(inject)了完全相同的 EntityManager 实例。为了进行设置,我使用了 guice 提供的 JpaPersistModule,并且我确信到目前为止我的设置中没有单例。

有人知道如何告诉 guice 在注入(inject)时创建 EntityManager 的新实例吗?

在另一种方法中,我尝试了 EntityManagerFactory 和 EntityManager 的自定义提供程序,并将 JpaPersistModule 排除在我的业务之外。这导致每个 DAO 都有一个 EntityManager 实例,但是 @Transactional 注释的方法当时没有被拦截。

如果能解决此问题,我将不胜感激。 到目前为止谢谢!

--- 编辑 ---

DAO 类被注入(inject)到使用它们的 Runnable 中。 Runnable 也是通过 Provider 提供的。我的模块配置如下所示:

public class RepositoryModule extends AbstractModule {

    @Override
    protected void configure() {

        // DAO bindings
        bind(IObjectStoreDao.class).to(ObjectStoreJpaController.class);
        bind(IPluginInstanceDao.class).to(PluginInstanceJpaController.class);
    }

    @Provides
    public PluginMonitor newMonitor(IPluginInstanceDao plugDao, IObjectStoreDao osDao) {
        PluginMonitor m = new PluginMonitor();
        m.setPluginInstanceDao(plugDao);
        m.setObjectStoreDao(osDao);
        return m;
    }
}

这里 PluginMonitor 是我的 Runnable。注入(inject)器本身是在我的主线程中创建的...这可能是问题所在?

最佳答案

这是非常相似的问题:How Guice injects singletons and non-singletons into multiple threads

对于您的 DAO,这应该可行。

public PluginInstanceJpaController implements IPluginInstanceDao {

    private Provider<EntityManager> emProvider;

    @Injected
    public PluginInstanceJpaController(Provider<EntityManager> emp) {
        this.em = emp;
    }

    @Transactional 
    public void create(PluginInstance foo) throws Exception {
        em.get().persist(foo);
    }
}

您应该使用Jpa Persistence Module或者创建自定义 EntityManager 提供程序,它将为每个 get() 调用返回新的 EntityManager,也可以使用 ThreadLocal 实现以确保 EntityManager 将跨线程共享。

关于java - Guice 在多线程应用程序中注入(inject) EntityManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12128552/

相关文章:

java - 在 Hibernate 中向多个表中插入数据

java - 如何使用@EmbeddedId 在两个表之间进行映射?

java - Google Guice 不就是另一个工厂吗?

java - 从并行线程结果更新 View

java - 欧元符号的转换

java - 如何跟踪从 eclipse-link JPA 到 DB 的 SQL 调用

java - Guice 中的绑定(bind) : Compile time dependencies

java - gwt 使用 guice - 引导或部署时发生的情况

Java代码风格

java - Spring MVC Controller 是否查找 ID 或名称?