因为我有一些需要传递给新生成的对象的泛型,我正在创建一个生成器。但是当生产者工作时,EntityManager
不会被注入,因为生成器使用运算符new
创建实例而不是使用CDI。
如何生成支持CDI的对象?
代码:
限定符:
@Qualifier
@Retention(RUNTIME)
@Target(
{ FIELD, TYPE, METHOD })
public @interface Multiselector
{
Class<? extends Dbo> clazz();
}
制片:
@SessionScoped
public class MultiselectorProducer implements Serializable
{
@Produces
@Multiselector(clazz = SpecialDbo.class)
public MultiselectorService<SpecialDbo> produce()
{
return new MultiselectorService<SpecialDbo>(SpecialDbo.class);
}
}
服务类:
@Stateful
@LocalBean
public class MultiselectorService<T extends Dbo> implements Serializable
{
@Inject
private EntityManager em;
private List<T> itemList;
public MultiselectorService()
{
}
public MultiselectorService(Class<? extends Dbo> clazz)
{
itemList = em.createQuery("some Sql String", clazz);
}
....
}
注意:EntityManager
是自定义crud服务,否则会正确注入
欢迎对代码提出任何改进建议。谢谢!
答案 0 :(得分:1)
你混合了很多无关的东西:
您的服务MultiselectorService
是一个EJB,您无法使用生产者生成它。创建应用程序后注册EJB,然后根据创建实例的范围进行注册。
你有一个方法public void MultiselectorService(Class<? extends Dbo> clazz)
,其名称类似于构造函数,它违反了约定。
假设你已经修复了那个方法作为构造函数,但是然后行'itemList = em.createQuery(“some Sql String”,clazz);' NPE会失败。因为只有在创建bean之后才会初始化em
。有两种方法可以做到:
将实体管理器注入构造函数(这是针对EJB规范的,如果您仍将使用EJB)
在带注释'@PostConstruct'的方法中执行初始化操作
您有EntityManager
的制作人吗?例如你不能只注入实体管理器,你需要提供作为EJB的资源,注释@PersistenceContext
我明白你想要实现的目标。主要问题是手动创建的bean不是由容器管理的,这意味着拦截器和装饰器将不适用(例如,PostConstruct和Transactional注释将不起作用)。检查here。到目前为止,实现这一目标的最佳方法是:
public interface SpecialDboMultiselectorService extends MultiselectorService {
}
@Stateless
public class SpecialDboMultiselectorServiceImpl extends MultiselectorServiceImpl<SpecialDbo> implements SpecialDboMultiselectorService
{
public SpecialDboMultiselectorServiceImpl() {
super(SpecialDbo.class);
}
}
public class MultiselectorServiceImpl<T extends Dbo> implements MultiselectorService {
@Inject
private EntityManager em;
private Class<? extends Dbo> clazz;
private List<T> itemList;
public MultiselectorService(Class<? extends Dbo> clazz) {
this.clazz = clazz
}
@PostConstruct
public void init() {
itemList = em.createQuery("some Sql String", clazz);
}
}
并注入SpecialDboMultiselectorService
。