Guice在多线程应用程序中注入了EntityManager [英] Guice injected EntityManager in multi threaded application

查看:250
本文介绍了Guice在多线程应用程序中注入了EntityManager的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Java SE 7开发桌面应用程序。该应用程序使用多个线程,并且在创建的每个线程中注入DAO类以访问我的数据库。作为持久层,我正在使用EclipseLink和JPA。使用构造函数注入将EntityManager注入到我的DAO类中,因为它不是线程安全的,所以我使用这样的Provder来实现这个方法:

I'm working on a desktop application using Java SE 7. The application uses multiple threads and in each thread that is created a DAO class is injected to gain access to my database. As persistence layer i'm using EclipseLink and JPA. The EntityManager is injected into my DAO class using constructor injection and since it is not thread safe, I went for the approach using a Provder like this:

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);
    }
}

然而,每个注入相同的EntityManager实例DAO。为了设置它,我使用了由guice提供的JpaPersistModule,我确信到目前为止我的设置中没有单例。

However, the very same EntityManager instance is injected into each DAO. For setting that up I used the JpaPersistModule as it is provided by guice and i'm sure that there are not singletons in my setup so far.

有谁知道怎么做告诉guice在注入时创建EntityManager的新实例?

Does anyone know how to tell guice to create a new instance of the EntityManager when injecting?

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

In another approach I tried custom providers for the EntityManagerFactory and the EntityManager and leaving the JpaPersistModule out of my business. This resulted in a EntityManager instance per DAO, however @Transactional annotated methods were not intercepted then.

我很感激这个问题的任何解决方案。
到目前为止,谢谢!

I'd appreciate any solution to this issue. Thanks so far!

---编辑---

注入DAO课程进入正在使用它们的Runnable。 Runnable也通过Provider提供。我的模块配置如下所示:

The DAO classes are injected into a Runnable that is using them. The Runnable is also provided through a Provider. My module configuration looks something like this:

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。 Injector本身是在我的主线程中创建的...可能这是问题吗?

Here PluginMonitor is my Runnable. The Injector itself is created in my main thread... might this have been the issue?

推荐答案

这是一个非常类似的问题: Guice如何注入单身人士和非单身人士进入多个线程

This is very similiar issue: How Guice injects singletons and non-singletons into multiple threads

对于你的DAO,这应该有效。

To your DAO, this should work.

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将在整个线程中共享。

You should use Jpa Persistence Module or create custom EntityManager provider, which will return new EntityManager for each get() call, also it can be implemented with ThreadLocal to ensure EntityManager will be shared across thread.

这篇关于Guice在多线程应用程序中注入了EntityManager的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆