2013-05-10 42 views
2

我想写一个CDI扩展,它从数据库加载一些实体(实际上是实现特定接口的groovy脚本)并将它们提供为bean,以便可以获取所有实现这个接口由CDI注入。我想到了。像下面这样:在CDI扩展中使用实体管理器

public class ExtensionClass implements Extension { 
    @Inject 
    EntityManager em; 

    public void afterBeanDiscovery(@Observes final AfterBeanDiscovery event, final BeanManager manager) { 
    Entity entity = em.find(); 
    //do sth with entity... 
    } 
} 

当我尝试注入实体管理器这种方式,它为空(这并不让我感到吃惊了,我没想到@注入到CDI扩展类的内部工作)。

是否有可能以某种方式访问​​CDI扩展中的实体管理器(例如,通过BeanManager)?或者我必须以另一种方式访问​​数据库?

回答

0

如果有人有兴趣如何让CDI扩展中的实体管理器,这是我做到了这一点。 首先,LightGuard说,你必须创建一个生产者,借此让该实体管理器:

@Produces 
@MyQualifier 
public javax.persistence.EntityManager create() { 
    return entityManager; 
} 

在CDI扩展,你则可以执行以下操作:

public class ScriptingExtension implements Extension { 
    public void afterBeanDiscovery(@Observes final AfterBeanDiscovery event, final BeanManager manager) { 
    final Set<Bean<?>> embeans = manager.getBeans(EntityManager.class); 
    final Bean<?> bean = manager.resolve(embeans); 

    final CreationalContext<?> creationalContext = manager.createCreationalContext(bean); 
    final EntityManager em = (EntityManager) manager.getReference(bean, EntityManager.class, creationalContext); 
    //do sth with entity manager... 
    } 
    } 

请注意,上在这种情况下,实体管理器只能在容器CDI生命周期的这一点上使用,而不是在早期(例如在ProcessAnnotatedType中)。在我的情况下,这是一个问题,因为我想否决一些豆子,为此我必须先截取。所以我选择使用直接的JNDI查找数据源来加载与我相关的信息,例如。像这样:

final InitialContext ctx = new InitialContext(); 
final DataSource dataSource = (DataSource) ctx.lookup("java:/jdbc/myDatasource"); 
1

您必须为EntityManager创建生产者。但是,我不会推荐在扩展中使用它,它不是可移植的(它可能适用于所有实现,但这将是其中一个灰色区域)。实体也需要生产,而不是让CDI容器处理它。如果您需要在应用程序开始时对实体进行操作,我建议您使用EJB规范中的@Startup

+0

谢谢,你的文章帮助我在正确的方向上搜索。 – 2013-05-17 10:31:12