使用可嵌入容器时,我的EntityManager保持为null。在常规Web应用程序中调用时,相同的代码效果很好。
测试代码:
package com.learning.business.car;
import static org.junit.Assert.assertEquals;
import java.util.List;
import javax.ejb.embeddable.EJBContainer;
import javax.naming.NamingException;
import org.junit.Test;
public class CarRepoTest {
@Test
public void testGetCarsByEjb() throws NamingException {
EJBContainer ec = EJBContainer.createEJBContainer();
CarRepo carRepo = (CarRepo) ec
.getContext()
.lookup("java:global/classes/CarRepo");
List<Car> cars = carRepo.getAll();
assertEquals(0, cars.size());
ec.close();
}
}
在调试上述代码时,ec.toString()
向我显示:
svContainerActive = true
svNamingInitialized = true
ivContext = com.ibm.ws.naming.java.javaURLContextRoot@fe720e63[super=com.ibm.ws.naming.java.javaURLContextImpl@fe720e63[super=com.ibm.ws.naming.urlbase.UrlContextImpl(java:)@fe720e63[_schemeId=java, _primaryLeafName=null, _strCtxID=ROOT CONTEXT, _ns=com.ibm.ws.naming.ipbase.NameSpace@d2d1a4d7[_nameSpaceName=java:comp(null, null, null), _nameSpaceID=2, _nameSpaceType=1, _contextsTable=java.util.HashMap@c8fb6403[size=2], _bindingsTable=java.util.HashMap@9cd644e1[size=2]]], _javaNameSpaceScope=COMPONENT SCOPE, _jns=javaNameSpaceImpl:{_appName=null,_moduleName=null,_componentName=null,_bootstrapAddress=rir:,_clientMode=ISOLATED,_componentNameSpaceLocation=LOCAL,_otherModuleNames=[],_applicationsRootProviderURL=corbaname:rir:/NameServiceApplicationsRoot#,_applicationRootProviderURL=null,_moduleRootProviderURL=null,_componentRootProviderURL=null,_ns=com.ibm.ws.naming.ipbase.NameSpace@d2d1a4d7[_nameSpaceName=java:comp(null, null, null), _nameSpaceID=2, _nameSpaceType=1, _contextsTable=java.util.HashMap@c8fb6403[size=2], _bindingsTable=java.util.HashMap@9cd644e1[size=2]]}], _caching=false, _rootCache=com.ibm.ws.naming.java.JavaNameSpaceCache@d10b63f9]
ivIsClosed = false
ivModules = [com.ibm.websphere.ejbcontainer.EmbeddableContainer$EmbeddableModule@9202003a[name=classes, file=C:\WorkSpaceRTC\javaee6\target\classes, metadata=com.ibm.ejs.csi.SharedEJBModuleMetaDataImpl@acb40850[embeddable#classes]]]
ivProperties = {enableProtocolSecurity=false}
ivServiceTokens = [sun.misc.Launcher$AppClassLoader@f3ba9f23:interface com.ibm.ws.runtime.service.MetaDataFactoryMgr, sun.misc.Launcher$AppClassLoader@f3ba9f23:interface com.ibm.wsspi.injectionengine.InjectionEngine]
EJB模块:
package com.learning.business.car;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
@Stateless
public class CarRepo {
@PersistenceContext
protected EntityManager em;
public List<Car> getAll() {
// "em" keeps null and the below line throws a NullPointerException
TypedQuery<Car> query = em.createQuery("SELECT c FROM Car c", Car.class);
return query.getResultList();
}
}
的persistence.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="javaee6" transaction-type="JTA">
<class>com.learning.business.car.Car</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1" />
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
</properties>
</persistence-unit>
</persistence>
例外:
CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "getAll" on bean "BeanId(embeddable#classes#CarRepo, null)". Exception data: java.lang.NullPointerException
at com.learning.business.car.CarRepo.getAll(CarRepo.java:18)
at com.learning.business.car.EJSLocalNSLCarRepo_a1ab5865.getAll(EJSLocalNSLCarRepo_a1ab5865.java)
at com.learning.business.car.CarRepoTest.testGetCarsByEjb(CarRepoTest.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(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.RemoteTestRunner.main(RemoteTestRunner.java:197)
另一方面,下面的代码在WebSphere应用程序中的xhtml页面使用时起作用:
package com.learning.app.car;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import com.learning.business.car.CarRepo;
@ManagedBean
public class CarBean {
@EJB
public CarRepo carRepo;
public Integer getCarsCount() {
// in a WebSphere application it works as expected (EntityManager is correctly injected in CarRepo)
return carRepo.getAll().size();
}
}
答案 0 :(得分:2)
建议在使用可嵌入容器时包含JPA瘦客户端。请查看以下链接以获取详细信息,可能会对您有所帮助Running an embeddable container
在嵌入式EJB中使用JPA开发应用程序时 容器,类路径必须包含JPA瘦客户端, com.ibm.ws.jpa.thinclient_n.0.jar,其中n是WebSphere® Application Server发布;例如,8.5版本8.5。 JPA 瘦客户端位于\ runtimes所在的根目录中 安装映像位于。