简体   繁体   English

在WebSphere Liberty中注入JPA实体管理器时出错

[英]Error Injecting the JPA Entity Manager in WebSphere Liberty

I have inherited a legacy application that initially was built with WebSphere 6.1 and then was migrated to WebSphere 8.0 running with JPA 2.0 and openJPA without issues. 我继承了一个遗留应用程序,该遗留应用程序最初是用WebSphere 6.1构建的,然后又被迁移到了运行JPA 2.0和openJPA的WebSphere 8.0。 We are migrating to WebSphere Liberty for strategic reasons. 由于战略原因,我们正在迁移到WebSphere Liberty。 We first tested on WebSphere Classic 8.5.5.8 and JPA and the entity manger has no issues there. 我们首先在WebSphere Classic 8.5.5.8和JPA上进行了测试,并且实体管理器那里没有问题。 However, on Liberty 8.5.5.8 I get the following exception: 但是,在Liberty 8.5.5.8上,出现以下异常:

javax.ejb.EJBException: The java:comp/env/com.xxx.xxxx.service.CHServiceBean/em reference of type javax.persistence.EntityManager for the CHServiceBean component in the CHServiceEJB.jar module of the CHServiceEAR application cannot be resolved. javax.ejb.EJBException:无法解析CHServiceEAR应用程序的CHServiceEJB.jar模块中CHServiceBean组件的javax.persistence.EntityManager类型的java:comp / env / com.xxx.xxxx.service.CHServiceBean / em引用。 at com.ibm.wsspi.injectionengine.InjectionBinding.getInjectionObject(InjectionBinding.java:1493) ..... [err] Caused by: [err] javax.ejb.EJBException: The java:comp/env/com.xxxx.xxxx.service.CHServiceBean/em reference of type javax.persistence.EntityManager for the CHServiceBean component in the CHServiceEJB.jar module of the CHServiceEAR application cannot be resolved. com.ibm.wsspi.injectionengine.InjectionBinding.getInjectionObject(InjectionBinding.java:1493)..... [err]原因:[err] javax.ejb.EJBException:java:comp / env / com.xxxx。无法解析CHServiceEAR应用程序的CHServiceEJB.jar模块中CHServiceBean组件的类型为javax.persistence.EntityManager的xxxx.service.CHServiceBean / em引用。 [err] at com.ibm.wsspi.injectionengine.InjectionBinding.getInjectionObject(InjectionBinding.java:1493) [err] at [internal classes] com.ibm.wsspi.injectionengine.InjectionBinding.getInjectionObject(InjectionBinding.java:1493)上的[err] [内部类]上的[err]

I had another EJB injection issue that was resolved through configuration of the binding files, however I am unable to resolve this issue. 我还有另一个EJB注入问题,可以通过配置绑定文件解决,但是我无法解决此问题。 I have two applications that each have their own EAR files but both run in the same Liberty JVM. 我有两个应用程序,每个应用程序都有自己的EAR文件,但是都在同一Liberty JVM中运行。 Application A runs the front end/UI logic while Application B is the back-end EJB / JPA interfaces. 应用程序A运行前端/ UI逻辑,而应用程序B是后端EJB / JPA接口。 In the project facets the JPA application is set to 2.0 (I wanted 2.1 but based on another thread JPA 2.0 and EJB 3.1 are as high as I can go at the moment...See my other thread topic here --> Eclipse Juno and JPA 2.1 support ). 在项目方面,JPA应用程序设置为2.0(我想使用2.1,但基于另一个线程,JPA 2.0和EJB 3.1达到了目前的水平……在这里查看我的其他线程主题-> Eclipse Juno和JPA 2.1支持 )。

Here is my server.xml file: 这是我的server.xml文件:

    <server description="new server">

    <!-- Enable features -->
    <featureManager>
        <feature>javaee-7.0</feature>
        <feature>localConnector-1.0</feature>
        <feature>distributedMap-1.0</feature>
        <feature>adminCenter-1.0</feature> 
        <feature>ssl-1.0</feature>
        <feature>usr:webCacheMonitor-1.0</feature>
        <feature>webCache-1.0</feature>
        <feature>ldapRegistry-3.0</feature>
    </featureManager>

    <!--  Admin Center Config Start -->
    <!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
    <httpEndpoint host="*" httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint"/>

    <keyStore id="defaultKeyStore" password="xxxxxx"/> 

    <basicRegistry id="basic"> 
          <user name="admin" password="xxxxx"/> 
          <user name="nonadmin" password="xxxxxx"/> 
    </basicRegistry> 

    <administrator-role> 
      <user>admin</user>
    </administrator-role>

    <remoteFileAccess> 
       <writeDir>${server.config.dir}</writeDir> 
    </remoteFileAccess>

    <!-- Automatically expand WAR files and EAR files -->
    <applicationManager autoExpand="true"/>
    <applicationMonitor updateTrigger="mbean"/>

    <enterpriseApplication id="CHNewCHRDMEAR" location="CHNewCHRDMEAR.ear" name="CHNewCHRDMEAR">
        <application-bnd>
            <security-role name="AllAuthenticated">
                <special-subject type="ALL_AUTHENTICATED_USERS"/>
            </security-role>
        </application-bnd>
    </enterpriseApplication>
    <enterpriseApplication id="CHServiceEAR" location="CHServiceEAR.ear" name="CHServiceEAR"/>

    <!--  JAAS Authentication Alias (Global) Config -->
    <authData id="dbUser" password="{xor}MzhmJT06ajI=" user="dbUser"/>

    <!--  JDBC Driver and Datasource Config -->
    <library id="DB2JCC4Lib">
        <fileset dir="C:\DB2\Jars" includes="db2jcc4.jar db2jcc_license_cisuz.jar"/>
    </library>

    <dataSource containerAuthDataRef="dbUser" id="CHTEST2" jndiName="jdbc/nextgen" type="javax.sql.XADataSource">
        <jdbcDriver libraryRef="DB2JCC4Lib"/>
        <properties.db2.jcc databaseName="CHTEST2" password="{xor}MzhmJT06ajI=" portNumber="60112" serverName="server.com" sslConnection="false" user="dbUser"/>
        <containerAuthData password="{xor}MzhmJT06ajI=" user="dbUser"/>
    </dataSource>

    <dataSource id="CHTEST2_RO" jndiName="jdbc/nextgen_RO" type="javax.sql.XADataSource">
        <jdbcDriver libraryRef="DB2JCC4Lib"/>
        <properties.db2.jcc databaseName="CHTEST2" password="{xor}MzhmJT06ajI=" portNumber="60112" serverName="server.com" sslConnection="false" user="dbUser"/>
        <containerAuthData password="{xor}MzhmJT06ajI=" user="dbUser"/>
    </dataSource>
<!-- More in file, but no included...-->
</server>

Here is my persistence.xml file: 这是我的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="CHService" transaction-type="JTA">
    <jta-data-source>jdbc/nextgen</jta-data-source>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="openjpa.jdbc.TransactionIsolation" value="read-uncommitted" /></properties></persistence-unit>
    <persistence-unit name="CHServiceRO" transaction-type="JTA">
        <jta-data-source>jdbc/nextgen_RO</jta-data-source>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
            <property name="openjpa.jdbc.TransactionIsolation" value="read-uncommitted" />
</properties>
</persistence-unit>
</persistence>

I *believe that we are relying solely on injection to get the context for JPA jndi lookups but that is because I don't see in our code any call to an initial context for any JPA specific JNDI names. *我相信我们完全依靠注入来获取JPA jndi查找的上下文,但是那是因为我在代码中看不到任何针对JPA特定JNDI名称的初始上下文的调用。 Below are my two anotated session beans from the EJB project: 以下是我从EJB项目获得的两个带注释的会话Bean:

a. 一种。 The CHService Bean: CHService Bean:

    @Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
@Local({ CHServiceLocal.class })
@Remote({ CHServiceRemote.class })
@Interceptors({ CHServiceLog.class })
@Resources({
        @Resource(name = "jdbc/nextgen", mappedName = "jdbc/nextgen", authenticationType = AuthenticationType.APPLICATION, shareable = true, type = javax.sql.DataSource.class),
        @Resource(name = "services/cache/CHBluepages", mappedName = "services/cache/CHBluepages", authenticationType = AuthenticationType.APPLICATION, shareable = true, type = com.ibm.websphere.cache.DistributedMap.class),
        @Resource(name = "services/cache/CHGeneric", mappedName = "services/cache/CHGeneric", authenticationType = AuthenticationType.APPLICATION, shareable = true, type = com.ibm.websphere.cache.DistributedMap.class) })
public class CHServiceBean extends AbstractCHServiceImpl implements
        CHService {

    @PersistenceContext(unitName = "CHService")
    private EntityManager em;

b. b。 The CHServiceRO bean: CHServiceRO bean:

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
@Local({CHServiceLocalRO.class})
@Remote({CHServiceRemoteRO.class})
@Interceptors({CHServiceROLog.class})
@Resources({
    @Resource(name="jdbc/nextgen_RO", mappedName="jdbc/nextgen_RO", authenticationType=AuthenticationType.APPLICATION, shareable=true, type=javax.sql.DataSource.class),
    @Resource(name="jdbc/nextgen", mappedName="jdbc/nextgen", authenticationType=AuthenticationType.APPLICATION, shareable=true, type=javax.sql.DataSource.class),
    @Resource(name="services/cache/CHBluepages", mappedName="services/cache/CHBluepages", authenticationType=AuthenticationType.APPLICATION, shareable=true, type=com.ibm.websphere.cache.DistributedMap.class),
    @Resource(name="services/cache/CHGeneric", mappedName="services/cache/CHGeneric", authenticationType=AuthenticationType.APPLICATION, shareable=true, type=com.ibm.websphere.cache.DistributedMap.class)
})
public class CHServiceBeanRO implements CHServiceRO {

    @PersistenceContext (unitName="CHServiceRO") private EntityManager em;

    private CHServiceBase ch;

    @PostConstruct
    private void init() { ch = new CHServiceBase(em); }

Here is a snippet from the Web.xml of the front-end application calling the JPA application: 这是调用JPA应用程序的前端应用程序的Web.xml中的片段:

<resource-ref id="ResourceRef_1436377001246">
        <res-ref-name>jdbc/nextgen</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Application</res-auth>
        <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>
    <resource-ref id="ResourceRef_1436377001247">
        <res-ref-name>jdbc/nextgen_RO</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Application</res-auth>
        <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>

Based on the post from Gas on this topic: java.lang.ClassCastException,Getting Entitymanager Via JNDI Lookup 基于Gas对此主题的帖子: java.lang.ClassCastException,通过JNDI查找获取Entitymanager

I also tried updating the web.xml with the following entries: 我还尝试使用以下条目更新web.xml:

<persistence-unit-ref>
  <persistence-unit-ref-name>chJPA</persistence-unit-ref-name>
  <persistence-unit-name>CHService</persistence-unit-name>
</persistence-unit-ref>
<persistence-unit-ref>
  <persistence-unit-ref-name>chJPA_RO</persistence-unit-ref-name>
  <persistence-unit-name>CHServiceRO</persistence-unit-name>
</persistence-unit-ref>

and the Bean code with: 和Bean代码,其中包含:

@PersistenceContext(name = "chJPA", unitName = "CHService")

and

@PersistenceContext (name="chJPA_RO", unitName="CHServiceRO")

Got the same error just with a different jndi name, ie The java:comp/env/chJPA reference of type javax.persistence.EntityManager for the CHServiceBean com.......etc etc. 只是使用不同的jndi名称而遇到相同的错误,即CHServiceBean com .......等的java:comp / env / chJPA类型为javax.persistence.EntityManager的引用。

Lastly, per this post: Error while accessing EntityManager - openjpa - WAS liberty profile It seems that maybe I can't have the full JavaEE 7 feature and run JPA 2.0? 最后,根据这篇文章: 访问EntityManager时出错-openjpa-WAS自由概要文件似乎我可能没有完整的JavaEE 7功能并无法运行JPA 2.0? Please advise! 请指教!

As in the post you are referring to - you cannot have <feature>javaee-7.0</feature> together with JPA 2.0, as it enables 2.1, thats why you have conflicts. 就像您在文章中所提到的那样-您不能将<feature>javaee-7.0</feature>与JPA 2.0一起使用,因为它启用了2.1,这就是为什么会有冲突的原因。

So you have 2 options: 因此,您有2个选择:

  • either use Java EE7 and JPA 2.1 要么使用Java EE7和JPA 2.1
  • or just enable required Java EE 6 features and then use JPA 2.0 或仅启用必需的Java EE 6功能,然后使用JPA 2.0

Since you are migrating from WAS 8.0, which doesn't support Java EE7 for now, easier choice might be to use the second option. 由于您要从WAS 8.0(目前不支持Java EE7)进行迁移,因此更容易的选择是使用第二个选项。 So try to remove javee-7.0 feature, and add ejbLite-3.1 and jpa-2.0 and whatever you need more. 因此,请尝试删除javee-7.0功能,并添加ejbLite-3.1jpa-2.0以及您需要的其他内容。

You are correct that you cannot have javaee-7.0 and the JPA 2.0 feature, as it enables the JPA 2.1 feature. 您正确地说,您不能具有javaee-7.0和JPA 2.0功能,因为它启用了JPA 2.1功能。 So the answer Gas gave is correct. 因此,加斯给出的答案是正确的。

I just wanted to point out since you said that you do want to go to JPA 2.1 eventually, once you work out your eclipse issues, that you should use the WebSphere Application Server Migration Toolkit to identify application changes needed when migrating from JPA 2.0 to JPA 2.1. 我只是想指出一下,因为您说过您确实希望最终使用JPA 2.1,一旦解决了日食问题,就应该使用WebSphere Application Server迁移工具包来识别从JPA 2.0迁移到JPA时需要的应用程序更改。 2.1。 The Liberty JPA 2.0 implementation is built on OpenJPA, whereas the JPA 2.1 implemtation is built on EclipseLink. Liberty JPA 2.0实现基于OpenJPA构建,而JPA 2.1实现基于EclipseLink构建。 The migration toolkit is downloadable for free on wasdev: https://developer.ibm.com/wasdev/downloads/#asset/tools-WebSphere_Application_Server_Migration_Toolkit 可以从wasdev上免费下载迁移工具包: https : //developer.ibm.com/wasdev/downloads/#asset/tools-WebSphere_Application_Server_Migration_Toolkit

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM