2012-11-05 32 views
4

我試圖注入一個實體管理器在DAO類和測試,使用的焊接容器,但我不斷收到獲取實例如下例外:WELD-000044無法從org.jboss.weld.bean-SE-模塊ProducerField

org.jboss.weld.exceptions.NullInstanceException:WELD-000044無法從org.jboss.weld.bean-SE-模塊ProducerField-com.playground.cdi_tutorial.beans.Resources.em 獲得實例at org.jboss.weld.bean.builtin.CallableMethodHandler.invoke(CallableMethodHandler.java:60) at org.jboss.weld.util.CleanableMethodHandler.invoke(CleanableMethodHandler.java:43) at javax.persistence.EntityManager _ $$ _javassist_2.createQuery(EntityManager的_ _ $$ javassist_2.java) at com.playground.cdi_tutorial.model.EventDAO.getAllEvents(EventDAO.java:22) at com.playground.cdi_tutorial.beans.ValidationService.validateEvenNumbers(ValidationService.java:23) at com.playground.cdi_tutorial.beans。 MyFactory.sayHi(MyFactory.java:15) 在com.playground.cdi_tutorial.beans.MyFactoryTest.should_say_bye(MyFactoryTest.java:26) 在sun.reflect.NativeMethodAccessorImpl.invoke0(本機方法) 在sun.reflect.NativeMethodAccessorImpl .invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.junit.runners .model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal。org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 在org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) 在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) 在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) 在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:193) 在org.junit.runners.ParentRunner $ 1.schedule( ParentRunner.java:52) 在org.junit.runners.ParentRunner.runChildren(ParentRunner。 java:191) at org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:42) at org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:184) at org.junit.runners。 ParentRunner.run(ParentRunner.java:236) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution。運行(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests( RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.Re moteTestRunner.main(RemoteTestRunner。Java的:197)

我嘗試如下注入實體管理器:

@Inject 
@EmProducer 
EntityManager em; 

其中EmProducer看起來是這樣的:

@Qualifier 
@Target({ TYPE, METHOD, PARAMETER, FIELD }) 
@Retention(RUNTIME) 
@Documented 
public @interface EmProducer { 

    public static final String UNIT_NAME = "cdi-tutorial"; 

}

而且生產類看起來像這樣:

public class Resources { 

@Produces 
@EmProducer 
@PersistenceContext(unitName = EmProducer.UNIT_NAME) 
private EntityManager em; 
     ... 
    } 

在我的測試中,當這行代碼命中Query q = em.createQuery(「from Employee」);我得到上面的例外。但是,實體經理em不是null。 PS:我使用WeldJUnit4Runner(http://www.hostettler.net/blog/2012/04/02/how-to-test-a-jsf-named-bean/)來運行我的測試。

我真的很感謝你的幫助。

謝謝!

回答

1

我建議使用Arquillian進行這種測試。它使得容器內測試非常容易(和快速)。您可以正常注入EntityManager,Arquillian負責其餘部分...

+0

謝謝,但這正是我想要避免的。我不需要應用程序服務器提供的所有服務,我只需要能夠注入託管的bean,包括實體管理器本身。我認爲問題與@PersistenceContext註釋未被Weld Container「識別」的事實有關。我會嘗試使用另一個Producer,通過在EntityManagerFactory的幫助下創建EntityManager。 – Maria

+0

好的,但只要你有時間就試試Arquillian。測試運行速度非常快,您可以將其部署到正在運行的服務器(遠程),或啓動和停止測試中的服務器(託管)。在http://arquillian.org/guides/testing_java_persistence/有關於測試持久性的教程。關於啓動所有服務,如果您使用的是Glassfish或JBoss,它們的啓動速度非常快,因爲不會加載未使用的服務。 – turgayze