如何控制客户端的CMT注入?
How to control CMT injection from clients?
假设我有一个 EJB。
@Stateless
public class PersistenceService {
@PersistenceContext(unitName="dependent")
private transient EntityManager entityManager;
}
有什么方法可以控制客户端的 unitName
值吗?
@RequestScoped
@Path("/persistence")
public class PersistenceResource {
//"some"
@Inject
private transient PersistenceService somePU;
//"other"
@Inject
private transient PersistenceService otherPU;
}
1) 为您的 PU 创建 2 个 CDI qualifiers:
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD})
public @interface SomePC {
}
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD})
public @interface OtherPC {
}
2) 然后将您的 PU 公开为 CDI bean
@ApplicationScoped
public class EntityManagerProducer {
@Produces
@PersistenceContext(unitName = "somePU")
@SomePC
private EntityManager em;
@Produces
@PersistenceContext(unitName = "otherPU")
@OtherPC
private EntityManager em;
}
3) 在您的服务中注入两个 EM:
@Stateless
public class PersistenceService {
@Inject
@SomePC
private emSome;
@Inject
@OtherPC
private emOther;
public SeomthingUseful doSomething(Context myContext){
getEntityManager(myContext);
...
}
private EntityManager getEntityManager(Context myContext){
if(myContext == SOME_PU)
return emSome;
return emOther;
}
}
4) 从您的客户端,您可以将上下文传递给 select 适当的 PU(您也可以为此目的创建一个 RequestScoped bean,在这种情况下您不必使用方法参数):
@RequestScoped
@Path("/persistence")
public class PersistenceResource {
@Inject
PersistenceService service;
public void myMethod(){
service.doSomething(myContext.SOME_PU);
}
}
上下文可以是具有您需要的不同值的枚举 (SOME_PU、OTHER_PU)。作为替代方案,您可以通过执行以下操作在您的服务中动态注入所有 EMs bean:
@Inject @Any Instance<EntityManager> emSource;
如果你遵循这条路,那么一切都会得到解释here
假设我有一个 EJB。
@Stateless
public class PersistenceService {
@PersistenceContext(unitName="dependent")
private transient EntityManager entityManager;
}
有什么方法可以控制客户端的 unitName
值吗?
@RequestScoped
@Path("/persistence")
public class PersistenceResource {
//"some"
@Inject
private transient PersistenceService somePU;
//"other"
@Inject
private transient PersistenceService otherPU;
}
1) 为您的 PU 创建 2 个 CDI qualifiers:
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD})
public @interface SomePC {
}
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD})
public @interface OtherPC {
}
2) 然后将您的 PU 公开为 CDI bean
@ApplicationScoped
public class EntityManagerProducer {
@Produces
@PersistenceContext(unitName = "somePU")
@SomePC
private EntityManager em;
@Produces
@PersistenceContext(unitName = "otherPU")
@OtherPC
private EntityManager em;
}
3) 在您的服务中注入两个 EM:
@Stateless
public class PersistenceService {
@Inject
@SomePC
private emSome;
@Inject
@OtherPC
private emOther;
public SeomthingUseful doSomething(Context myContext){
getEntityManager(myContext);
...
}
private EntityManager getEntityManager(Context myContext){
if(myContext == SOME_PU)
return emSome;
return emOther;
}
}
4) 从您的客户端,您可以将上下文传递给 select 适当的 PU(您也可以为此目的创建一个 RequestScoped bean,在这种情况下您不必使用方法参数):
@RequestScoped
@Path("/persistence")
public class PersistenceResource {
@Inject
PersistenceService service;
public void myMethod(){
service.doSomething(myContext.SOME_PU);
}
}
上下文可以是具有您需要的不同值的枚举 (SOME_PU、OTHER_PU)。作为替代方案,您可以通过执行以下操作在您的服务中动态注入所有 EMs bean:
@Inject @Any Instance<EntityManager> emSource;
如果你遵循这条路,那么一切都会得到解释here