【问题标题】:EntityManager not being injected in EJB module instantiated by WebSphere embeddable container while JUnit testing在 JUnit 测试时,EntityManager 没有被注入到由 WebSphere 可嵌入容器实例化的 EJB 模块中
【发布时间】:2014-09-03 18:39:52
【问题描述】:

使用可嵌入容器时,我的 EntityManager 保持为空。在常规 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();
    }
}

【问题讨论】:

    标签: jpa junit ejb websphere java-ee-6


    【解决方案1】:

    使用可嵌入容器时,建议包含 JPA 瘦客户端。查看以下链接了解详细信息,也许它会对您有所帮助Running an embeddable container

    在可嵌入 EJB 中使用 JPA 开发应用程序时 容器,类路径必须包含 JPA 瘦客户端, com.ibm.ws.jpa.thinclient_n.0.jar,其中 n 是 WebSphere® 应用服务器发布;例如,8.5 代表版本 8.5。 JPA 瘦客户端位于 \runtimes 的根目录中 安装映像位于。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-03
      • 1970-01-01
      • 1970-01-01
      • 2013-04-21
      相关资源
      最近更新 更多