首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在泽西/ EntityManager应用程序中正确配置hk2?

如何在泽西/ EntityManager应用程序中正确配置hk2?
EN

Stack Overflow用户
提问于 2015-01-20 12:07:27
回答 1查看 8.5K关注 0票数 7

我有一个jersey-2 / hk2应用程序,它使用JPA持久性。EntityManager在启动时绑定如下

代码语言:javascript
复制
public MyApplication() {
    // ...
    register(new AbstractBinder() {
        @Override
        public void configure() {
          bindFactory(EmFactory.class)
            .to(EntityManager.class)
            .in(RequestScoped.class);
        }
    });
}

工厂的阶级是

代码语言:javascript
复制
public class EmFactory implements Factory<EntityManager> {

    private static final String PERSISTENCE_UNIT = "unit";

    private EntityManagerFactory emf;
    private CloseableService closeableService;

    @Inject
    public EmFactory(@Named(PERSISTENCE_UNIT) String persistenceUnit,
            CloseableService closeableService) {
        emf = Persistence.createEntityManagerFactory(persistenceUnit);
        this.closeableService = closeableService;
    }

    @Override
    public EntityManager provide() {
        final EntityManager entityManager = emf.createEntityManager();
        closeableService.add(new Closeable() {

            @Override
            public void close() throws IOException {
                if(entityManager.isOpen()) {
                    entityManager.close();
                }
            }
        });
        return entityManager;
    }

    @Override
    public void dispose(EntityManager entityManager) {
        if(entityManager.isOpen()) {
            entityManager.close();
        }
    }
}

这是可行的,但是对于每个请求,我都会在日志中得到一个关于EntityManager已经注册的警告:

代码语言:javascript
复制
HHH000436: Entity manager factory name (unit) is already registered. \
  If entity manager will be clustered or passivated, specify a unique \
  value for property 'hibernate.ejb.entitymanager_factory_name'

我做错了什么?在jersey-2 / hk2应用程序中初始化EntityManager的正确方法是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-24 06:18:33

一种选择是不在EMFactory中创建一个新的EMFactory(在请求范围内),您可以为EntityManagerFactory创建一个单例工厂,然后将EntityManagerFactory注入到EMFactory中。

代码语言:javascript
复制
public class EMFFactory implements Factory<EntityManagerFactory> {
    private final EntityManagerFactory emf;
    public EMFFactory (){
        emf = Persistence.createEntityManagerFactory(persistenceUnit);
    }
    public EntityManagerFactory provide() {
        return emf;
    }
    ...
}

public class EMFactory implements Factory<EntityManager> {
    private final EntityManager em;

    @Inject
    public EMFactory (EntityManagerFactory emf){
        em = emf.createEntityManager();
    }
    public EntityManager provide() {
        return em;
    }
    ...
}

还没有测试这个精确的实现,但是它应该是这样的。我以前用过这个图案。

代码语言:javascript
复制
register(new AbstractBinder() {
    @Override
    public void configure() {
      bindFactory(EMFFactory.class).to(EntityManagerFactory.class).in(Singleton.class);
      bindFactory(EMFactory.class).to(EntityManager.class).in(RequestScoped.class);
    }
});

更新

关于上面的例子,有一点要注意的是,它没有清理资源,即EntityManager应该是关闭的;它不会关闭自己。在dispose类中有一个我们需要重写的Factory方法,但根据我的经验,泽西从未调用过这个方法。

我们可以做的是将EntityManager添加到CloseableService中。

代码语言:javascript
复制
public class EMFactory implements Factory<EntityManager> {
    private final EntityManagerFactory emf;
    private final CloseableService closeService;

    @Inject
    public EMFactory (EntityManagerFactory emf, CloseableService closeService){
        this.emf = emf;
        this.closeService = closeService;
    }
    public EntityManager provide() {
        final EntityManager em = emf.createEntityManager();
        this.closeService.add(new Closeable(){
            @Override
            public void close() {
                em.close();
            }
        });
        return em;
    }
    ...
}

这样可以确保在请求结束时关闭EntityManager

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28045019

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档