agn*_*nul 7 java dependency-injection jpa jersey-2.0 hk2
我有一个使用JPA持久性的jersey-2/hk2应用程序.将EntityManager在这样的约束启动
public MyApplication() {
// ...
register(new AbstractBinder() {
@Override
public void configure() {
bindFactory(EmFactory.class)
.to(EntityManager.class)
.in(RequestScoped.class);
}
});
}
Run Code Online (Sandbox Code Playgroud)
与工厂类一样
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这工作,但然后对于每个请求我在日志中收到有关已注册的EntityManager的警告:
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'
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?在jersey-2/hk2应用程序中初始化EntityManager的正确方法是什么?
Pau*_*tha 14
一种选择是不是创建一个新的EntityManagerFactory中EMFactory(这是在请求范围内),您可以创建为一个单独的工厂EntityManagerFactory,然后就注射EntityManagerFactory到EMFactory.
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;
}
...
}
Run Code Online (Sandbox Code Playgroud)
没有测试过这个确切的实现,但它看起来应该是这样的.我以前用过这种模式.
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);
}
});
Run Code Online (Sandbox Code Playgroud)
关于上述例子需要注意的一点是,它不会清理资源,即EntityManager应该关闭; 它不会自行关闭.我们需要覆盖类中的一个dispose方法Factory,但根据我的经验,Jersey从不调用它.
我们能做的是添加EntityManager到[ CloseableService] [1]
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;
}
...
}
Run Code Online (Sandbox Code Playgroud)
这样EntityManager就确保在请求结束时关闭.
| 归档时间: |
|
| 查看次数: |
7376 次 |
| 最近记录: |