当前位置: 首页 > 知识库问答 >
问题:

多线程应用中的Guice注入EntityManager

公孙成仁
2023-03-14

我正在使用JavaSE7开发一个桌面应用程序。应用程序使用多个线程,在创建的每个线程中,都会注入一个DAO类来访问我的数据库。作为持久层,我使用EclipseLink和JPA。EntityManager是使用构造函数注入注入注入到我的DAO类中的,因为它不是线程安全的,所以我使用了如下验证程序:

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,我确信到目前为止,我的设置中没有单例。

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

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

如果能解决这个问题,我将不胜感激。非常感谢!

---编辑---

DAO类被注入到正在使用它们的Runnable中。Runnable也通过提供者提供。我的模块配置如下所示:

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

共有2个答案

卢雅惠
2023-03-14

我对JPA不太熟悉,但希望我仍能帮上忙:-)

如果您查看EntityManagerProvider的源代码,您可以看到有一个ThreadLocal

此外,您可以将构造函数编写为:

@Inject
public FooDao(EntityManager emp) {
    this.em = emp;
}

Guice将为您发挥神奇的作用,确定EntityManager Provider提供了EntityManager实例,并将调用EntityManager Provider实例上的get(),以获得一个EntityManager提供给您的构造函数。

蒋斯伯
2023-03-14

这是一个非常相似的问题:Guice如何将单例和非单例注入多个线程

对你的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持久性模块或创建自定义EntityManager提供程序,它将为每个get()调用返回新的EntityManager,还可以使用ThreadLocal实现,以确保EntityManager在线程之间共享。

 类似资料:
  • 我正在使用Guice和Dropwizard开发一个应用程序,在其中我们创建了不同的包,如Guice包、migrations包等,并将它们添加到initialize()方法中的bootstrap中。 注意:我知道另一种方法,您可以在run()方法中创建Module类的对象,用于创建注入器(配置和环境对象在MyModule类的构造函数中作为参数传递)。但这需要我在run()方法中注册所有托管对象和所有

  • 我正在努力实现DI,特别是使用guice的构造函数注入。我很难理解如何将泛型的类类型注入到构造函数中。 我的课程如下: 我可以在运行时使用guice将类的类型注入构造函数吗?简而言之,我可以使用guice注入Foo构造函数吗?

  • 我使用< code>Cucumber和< code>Guice作为DI。我遇到了以下问题:我有一个步骤,即 我让这个类作为测试运行它 有一个 由我的使用,我定义了cucumber.properties,我定义了还有一个包含方案的功能文件。现在一切都在工作。 不,我想使用其他MyService实现运行MyStep步骤(当然我不会重复MyStep的代码)我定义了一个具有新场景和新测试类的新功能文件 现

  • 问题内容: 我正在尝试使用Guice注入通用类型。我的Repository 位于Cursor类中。 因此,当我创建Cursor 时,我还希望Guice将我的存储库注入Repository 。有没有办法做到这一点? 问题答案: 您必须使用: 要获取的实例,则需要: 在FAQ中有更多细节。

  • 问题内容: 我将python解释器嵌入到多线程C应用程序中,对于应该使用哪些API来确保线程安全,我有些困惑。 从我收集到的信息来看,嵌入python时,在调用任何其他Python C API调用之前,由嵌入器负责GIL锁定。这是通过以下功能完成的: 但是,仅此一项似乎还不够。我仍然遇到随机崩溃,因为它似乎并未为Python API提供互斥。 阅读更多文档后,我还添加了: 在致电之后,但这就是令人

  • 我正在使用 scala play 2.5,在尝试在我的一个控制器中注入对象时出现以下错误。我正在使用 play 给出的默认注入框架,即 Guice。 这是控制器: 以下是我想注入的服务: 这就是我使用它的方式: