(OpenJPA/WAS) 如何为容器管理的实体管理器使用容器管理的身份验证

(OpenJPA/WAS) How to use the Container Managed Authentication for the Container Managed Entity Manager

Objective

了解如何配置 WAS 或 OpenJPA 以将容器管理的身份验证与容器管理的实体管理器一起使用。

问题

试图通过在 JNDI 中注册为 "jdbc/DB2"(指的是 Oracle)的 JDBC 数据源访问 Oracle 数据库,定义在 persistence.xml.

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
    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_1_0.xsd">
    <persistence-unit name="DB2AccountUnit" transaction-type="JTA">
        <jta-data-source>jdbc/DB2</jta-data-source>
        <class>sample.jpa.Db2account</class>
        <properties>
            <property name="openjpa.Log" value="File=C:/opt/openjpa/org.apache.openjpa.log, DefaultLevel=INFO, Runtime=TRACE, Tool=INFO, SQL=TRACE, JDBC=TRACE" />
            <!-- Without these properties, the error is caused.
            <property name="openjpa.ConnectionUserName" value="User" />
            <property name="openjpa.ConnectionPassword" value="Password" />
             -->
        </properties>
    </persistence-unit>
</persistence>

然而,当访问持久化单元的容器管理实体管理器时,抛出 ORA-01017 invalid usrname/password。如果在 persistence.xml 中指定 ConnectionUserName/ConnectionPassword,则错误已解决。

错误

[26/09/15 20:56:31:584 AEST] 00000090 SystemErr     
R <openjpa-2.2.3-SNAPSHOT-r422266:1686911 fatal general error> org.apache.openjpa.persistence.PersistenceException: 
ORA-01017: invalid username/password; logon denied
DSRA0010E: SQL State = 72000, Error Code = 1,017
[26/09/15 20:56:31:585 AEST] 00000090 SystemErr     R   at org.apache.openjpa.jdbc.sql.DBDictionaryFactory.newDBDictionary(DBDictionaryFactory.java:102)
...
[26/09/15 20:56:31:601 AEST] 00000090 SystemErr     R   at sample.jpa.servlet.CreateAccount.doPost(CreateAccount.java:23)

WAS

使用实体管理器的 Servlet
原文来自 IBM developerWorks 文章。在servlet实例变量中注入实体管理器不是多线程安全的,而是为了测试。

@WebServlet("/CreateAccount")
public class CreateAccount extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    private static final long serialVersionUID = 1L;

    @PersistenceContext(unitName="DB2AccountUnit")
    EntityManager em;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    synchronized protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        InitialContext context = null;
        UserTransaction ut = null;

        try {
            context = new InitialContext();
            ut = (UserTransaction)context.lookup("java:comp/UserTransaction");

            if(ut == null){
                System.out.println("UserTransactin is NULL");
            }

            //em.getTransaction().begin();
            ut.begin();

            long accno = Long.parseLong(request.getParameter("ACCNO"));
            Db2account account1 = em.find(Db2account.class, accno); // <----- Error occurs here.

            if (account1 != null) {
                throw new AccountException("Error : sample.jpa.servlet.CreateAccount : Account Number already exists:" + accno);
            } else {
                SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy");
                java.sql.Date dbDate = new java.sql.Date(format.parse(request.getParameter("DOP"), new ParsePosition(0)).getTime());

                Db2account account = new Db2account();
                account.setOwner(request.getParameter("OWNERNAME"));
                account.setAccno(accno);
                account.setAccountType(request.getParameter("ACCOUNTTYPE"));
                account.setBalance(new BigDecimal(request.getParameter("BALANCE")));
                account.setDateOpen(dbDate);

                em.persist(account);
                // em.getTransaction().commit();
                ut.commit();
                response.sendRedirect("Create_Account.jsp");
            }
        } catch (Exception e) {
            e.printStackTrace();
            //em.getTransaction().rollback();
            try{
                ut.rollback();
            } catch (SystemException se){
                se.printStackTrace();
            }
        }
    }
}

问题

请帮助理解为什么不使用 JAAS 以及如何配置 WAS 或 JPA 来使用它。

环境

面向开发人员的 IBM WAS 8.5.5.7 (Apache openjpa-2.2.3-SNAPSHOT-r422266)
Oracle 数据库 11g 企业版 11.2.0.1.0 版 - 64 位生产
Windows 7 64 位 DELL Latitude core i7 2.8GHz 8G 内存和 SSD HDD

日志

应用程序启动时出现 Oracle 错误

[26/09/15 20:39:59:860 AEST] 0000008e ApplicationMg A   WSVR0200I: Starting application: Account
[26/09/15 20:40:00:062 AEST] 0000008e driver        E   CE9D1D8D Throwing SQLException: ORA-01017: invalid username/password; logon denied
1017
[26/09/15 20:40:00:065 AEST] 0000008e driver        E   DABC15C4 Throwing SQLException: 430
[26/09/15 20:40:00:089 AEST] 0000008e Runtime       W   CWWJP9991W: openjpa.Runtime: Warn: An error occurred while registering a ClassTransformer with JPAPUnitInfo(PuId=Account#lib/AccountDB2JPA.jar#DB2AccountUnit_HOGE)@504fa90. The error has been consumed. To see it, set your openjpa.Runtime log level to TRACE. Load-time class transformation will not be available.
[26/09/15 20:40:00:188 AEST] 0000008e driver        E   33A50E58 Throwing SQLException: ORA-01017: invalid username/password; logon denied
1017
[26/09/15 20:40:00:190 AEST] 0000008e driver        E   C5B591D4 Throwing SQLException: 430
[26/09/15 20:40:00:206 AEST] 0000008e Runtime       W   CWWJP9991W: openjpa.Runtime: Warn: An error occurred while registering a ClassTransformer with JPAPUnitInfo(PuId=Account#AccountWeb.war#DB2AccountUnit_HOGE)@4167230b. The error has been consumed. To see it, set your openjpa.Runtime log level to TRACE. Load-time class transformation will not be available.
[26/09/15 20:40:00:315 AEST] 0000008e driver        E   FDD70E84 Throwing SQLException: ORA-01017: invalid username/password; logon denied
1017
[26/09/15 20:40:00:317 AEST] 0000008e driver        E   CB5DFD5C Throwing SQLException: 430
[26/09/15 20:40:00:331 AEST] 0000008e Runtime       W   CWWJP9991W: openjpa.Runtime: Warn: An error occurred while registering a ClassTransformer with JPAPUnitInfo(PuId=Account#AccountWeb.war#DerbyAccountUnit)@e9b08d89. The error has been consumed. To see it, set your openjpa.Runtime log level to TRACE. Load-time class transformation will not be available.
[26/09/15 20:40:00:333 AEST] 0000008e Runtime       I   CWWJP9990I: openjpa.Runtime: Info: OpenJPA dynamically loaded a validation provider.
[26/09/15 20:40:00:420 AEST] 0000008e WASSessionCor I SessionContextRegistry getSessionContext SESN0176I: Will create a new session context for application key default_host/AccountWeb
[26/09/15 20:40:00:470 AEST] 0000008e ApplicationMg A   WSVR0221I: Application started: Account

执行CreateAccount时出现Oracle错误

[26/09/15 20:56:31:584 AEST] 00000090 SystemErr     R <openjpa-2.2.3-SNAPSHOT-r422266:1686911 fatal general error> org.apache.openjpa.persistence.PersistenceException: ORA-01017: invalid username/password; logon denied
 DSRA0010E: SQL State = 72000, Error Code = 1,017
[26/09/15 20:56:31:585 AEST] 00000090 SystemErr     R   at org.apache.openjpa.jdbc.sql.DBDictionaryFactory.newDBDictionary(DBDictionaryFactory.java:102)
[26/09/15 20:56:31:585 AEST] 00000090 SystemErr     R   at org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl.getDBDictionaryInstance(JDBCConfigurationImpl.java:603)
[26/09/15 20:56:31:586 AEST] 00000090 SystemErr     R   at org.apache.openjpa.jdbc.meta.MappingRepository.endConfiguration(MappingRepository.java:1518)
[26/09/15 20:56:31:586 AEST] 00000090 SystemErr     R   at org.apache.openjpa.lib.conf.Configurations.configureInstance(Configurations.java:531)
[26/09/15 20:56:31:593 AEST] 00000090 SystemErr     R   at org.apache.openjpa.lib.conf.Configurations.configureInstance(Configurations.java:456)
[26/09/15 20:56:31:594 AEST] 00000090 SystemErr     R   at org.apache.openjpa.lib.conf.PluginValue.instantiate(PluginValue.java:121)
[26/09/15 20:56:31:594 AEST] 00000090 SystemErr     R   at org.apache.openjpa.conf.MetaDataRepositoryValue.instantiate(MetaDataRepositoryValue.java:68)
[26/09/15 20:56:31:595 AEST] 00000090 SystemErr     R   at org.apache.openjpa.lib.conf.ObjectValue.instantiate(ObjectValue.java:83)
[26/09/15 20:56:31:595 AEST] 00000090 SystemErr     R   at org.apache.openjpa.conf.OpenJPAConfigurationImpl.newMetaDataRepositoryInstance(OpenJPAConfigurationImpl.java:967)
[26/09/15 20:56:31:596 AEST] 00000090 SystemErr     R   at org.apache.openjpa.conf.OpenJPAConfigurationImpl.getMetaDataRepositoryInstance(OpenJPAConfigurationImpl.java:958)
[26/09/15 20:56:31:596 AEST] 00000090 SystemErr     R   at org.apache.openjpa.kernel.AbstractBrokerFactory.makeReadOnly(AbstractBrokerFactory.java:642)
[26/09/15 20:56:31:597 AEST] 00000090 SystemErr     R   at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:203)
[26/09/15 20:56:31:597 AEST] 00000090 SystemErr     R   at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:156)
[26/09/15 20:56:31:597 AEST] 00000090 SystemErr     R   at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:228)
[26/09/15 20:56:31:598 AEST] 00000090 SystemErr     R   at com.ibm.ws.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:72)
[26/09/15 20:56:31:598 AEST] 00000090 SystemErr     R   at com.ibm.ws.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:35)
[26/09/15 20:56:31:599 AEST] 00000090 SystemErr     R   at com.ibm.ws.jpa.management.JPAEMPool.getEntityManager(JPAEMPool.java:170)
[26/09/15 20:56:31:599 AEST] 00000090 SystemErr     R   at com.ibm.ws.jpa.management.JPATxEntityManager.getEMInvocationInfo(JPATxEntityManager.java:259)
[26/09/15 20:56:31:600 AEST] 00000090 SystemErr     R   at com.ibm.ws.jpa.management.JPATxEntityManager.getEMInvocationInfo(JPATxEntityManager.java:191)
[26/09/15 20:56:31:600 AEST] 00000090 SystemErr     R   at com.ibm.ws.jpa.management.JPAEntityManager.getTransaction(JPAEntityManager.java:421)
[26/09/15 20:56:31:601 AEST] 00000090 SystemErr     R   at sample.jpa.servlet.CreateAccount.doPost(CreateAccount.java:23)
[26/09/15 20:56:31:601 AEST] 00000090 SystemErr     R   at javax.servlet.http.HttpServlet.service(HttpServlet.java:595)
[26/09/15 20:56:31:602 AEST] 00000090 SystemErr     R   at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
[26/09/15 20:56:31:602 AEST] 00000090 SystemErr     R   at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1232)
[26/09/15 20:56:31:602 AEST] 00000090 SystemErr     R   at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:781)
[26/09/15 20:56:31:602 AEST] 00000090 SystemErr     R   at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:480)
[26/09/15 20:56:31:603 AEST] 00000090 SystemErr     R   at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:178)
[26/09/15 20:56:31:605 AEST] 00000090 SystemErr     R   at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1114)
[26/09/15 20:56:31:605 AEST] 00000090 SystemErr     R   at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3926)
[26/09/15 20:56:31:605 AEST] 00000090 SystemErr     R   at com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:304)
[26/09/15 20:56:31:605 AEST] 00000090 SystemErr     R   at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:1007)
[26/09/15 20:56:31:605 AEST] 00000090 SystemErr     R   at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1817)
[26/09/15 20:56:31:606 AEST] 00000090 SystemErr     R   at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:200)
[26/09/15 20:56:31:606 AEST] 00000090 SystemErr     R   at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:463)
[26/09/15 20:56:31:606 AEST] 00000090 SystemErr     R   at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:530)
[26/09/15 20:56:31:606 AEST] 00000090 SystemErr     R   at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:316)
[26/09/15 20:56:31:606 AEST] 00000090 SystemErr     R   at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:287)
[26/09/15 20:56:31:607 AEST] 00000090 SystemErr     R   at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:214)
[26/09/15 20:56:31:607 AEST] 00000090 SystemErr     R   at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:113)
[26/09/15 20:56:31:607 AEST] 00000090 SystemErr     R   at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:175)
[26/09/15 20:56:31:607 AEST] 00000090 SystemErr     R   at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
[26/09/15 20:56:31:607 AEST] 00000090 SystemErr     R   at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)
[26/09/15 20:56:31:607 AEST] 00000090 SystemErr     R   at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)
[26/09/15 20:56:31:608 AEST] 00000090 SystemErr     R   at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204)
[26/09/15 20:56:31:608 AEST] 00000090 SystemErr     R   at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775)
[26/09/15 20:56:31:608 AEST] 00000090 SystemErr     R   at com.ibm.io.async.ResultHandler.run(ResultHandler.java:905)
[26/09/15 20:56:31:608 AEST] 00000090 SystemErr     R   at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1881)
[26/09/15 20:56:31:609 AEST] 00000090 SystemErr     R Caused by: java.sql.SQLException: ORA-01017: invalid username/password; logon denied
 DSRA0010E: SQL State = 72000, Error Code = 1,017
[26/09/15 20:56:31:609 AEST] 00000090 SystemErr     R   at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:459)
[26/09/15 20:56:31:610 AEST] 00000090 SystemErr     R   at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:392)
[26/09/15 20:56:31:610 AEST] 00000090 SystemErr     R   at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:384)
[26/09/15 20:56:31:611 AEST] 00000090 SystemErr     R   at oracle.jdbc.driver.T4CTTIfun.processError(T4CTTIfun.java:767)
[26/09/15 20:56:31:611 AEST] 00000090 SystemErr     R   at oracle.jdbc.driver.T4CTTIoauthenticate.processError(T4CTTIoauthenticate.java:450)
[26/09/15 20:56:31:612 AEST] 00000090 SystemErr     R   at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:539)
[26/09/15 20:56:31:612 AEST] 00000090 SystemErr     R   at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:235)
[26/09/15 20:56:31:612 AEST] 00000090 SystemErr     R   at oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:382)
[26/09/15 20:56:31:612 AEST] 00000090 SystemErr     R   at oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:822)
[26/09/15 20:56:31:612 AEST] 00000090 SystemErr     R   at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:477)
[26/09/15 20:56:31:613 AEST] 00000090 SystemErr     R   at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:564)
[26/09/15 20:56:31:613 AEST] 00000090 SystemErr     R   at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:251)
[26/09/15 20:56:31:613 AEST] 00000090 SystemErr     R   at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:29)
[26/09/15 20:56:31:613 AEST] 00000090 SystemErr     R   at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:563)
[26/09/15 20:56:31:613 AEST] 00000090 SystemErr     R   at oracle.jdbc.pool.OracleDataSource.getPhysicalConnection(OracleDataSource.java:454)
[26/09/15 20:56:31:613 AEST] 00000090 SystemErr     R   at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:328)
[26/09/15 20:56:31:614 AEST] 00000090 SystemErr     R   at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPhysicalConnection(OracleConnectionPoolDataSource.java:379)
[26/09/15 20:56:31:614 AEST] 00000090 SystemErr     R   at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPooledConnection(OracleConnectionPoolDataSource.java:165)
[26/09/15 20:56:31:614 AEST] 00000090 SystemErr     R   at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPooledConnection(OracleConnectionPoolDataSource.java:111)
[26/09/15 20:56:31:614 AEST] 00000090 SystemErr     R   at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper.run(InternalGenericDataStoreHelper.java:1365)
[26/09/15 20:56:31:615 AEST] 00000090 SystemErr     R   at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:118)
[26/09/15 20:56:31:615 AEST] 00000090 SystemErr     R   at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper.getPooledConnection(InternalGenericDataStoreHelper.java:1384)
[26/09/15 20:56:31:615 AEST] 00000090 SystemErr     R   at com.ibm.ws.rsadapter.spi.WSRdbDataSource.getPooledConnection(WSRdbDataSource.java:2150)
[26/09/15 20:56:31:615 AEST] 00000090 SystemErr     R   at com.ibm.ws.rsadapter.spi.WSManagedConnectionFactoryImpl.getConnection(WSManagedConnectionFactoryImpl.java:1787)
[26/09/15 20:56:31:615 AEST] 00000090 SystemErr     R   at com.ibm.ws.rsadapter.spi.WSManagedConnectionFactoryImpl.createManagedConnection(WSManagedConnectionFactoryImpl.java:1557)
[26/09/15 20:56:31:616 AEST] 00000090 SystemErr     R   at com.ibm.ws.rsadapter.spi.WSManagedConnectionFactoryImpl.createManagedConnection(WSManagedConnectionFactoryImpl.java:1113)
[26/09/15 20:56:31:616 AEST] 00000090 SystemErr     R   at com.ibm.ejs.j2c.FreePool.createManagedConnectionWithMCWrapper(FreePool.java:2161)
[26/09/15 20:56:31:616 AEST] 00000090 SystemErr     R   at com.ibm.ejs.j2c.FreePool.createOrWaitForConnection(FreePool.java:1839)
[26/09/15 20:56:31:616 AEST] 00000090 SystemErr     R   at com.ibm.ejs.j2c.PoolManager.reserve(PoolManager.java:3818)
[26/09/15 20:56:31:616 AEST] 00000090 SystemErr     R   at com.ibm.ejs.j2c.PoolManager.reserve(PoolManager.java:3094)
[26/09/15 20:56:31:617 AEST] 00000090 SystemErr     R   at com.ibm.ejs.j2c.ConnectionManager.allocateMCWrapper(ConnectionManager.java:1548)
[26/09/15 20:56:31:617 AEST] 00000090 SystemErr     R   at com.ibm.ejs.j2c.ConnectionManager.allocateConnection(ConnectionManager.java:1031)
[26/09/15 20:56:31:617 AEST] 00000090 SystemErr     R   at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:644)
[26/09/15 20:56:31:618 AEST] 00000090 SystemErr     R   at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:611)
[26/09/15 20:56:31:618 AEST] 00000090 SystemErr     R   at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getContainerManagedConnection(WSJdbcDataSource.java:958)
[26/09/15 20:56:31:619 AEST] 00000090 SystemErr     R   at com.ibm.ws.jpa.management.JPACMDataSource.getConnection(JPACMDataSource.java:44)
[26/09/15 20:56:31:619 AEST] 00000090 SystemErr     R   at org.apache.openjpa.lib.jdbc.DelegatingDataSource.getConnection(DelegatingDataSource.java:110)
[26/09/15 20:56:31:619 AEST] 00000090 SystemErr     R   at org.apache.openjpa.lib.jdbc.DecoratingDataSource.getConnection(DecoratingDataSource.java:87)
[26/09/15 20:56:31:620 AEST] 00000090 SystemErr     R   at org.apache.openjpa.jdbc.sql.DBDictionaryFactory.newDBDictionary(DBDictionaryFactory.java:91)
[26/09/15 20:56:31:620 AEST] 00000090 SystemErr     R   ... 46 more

JNDI 命名空间(服务器 1)

==============================================================================
Name Space Dump
   Context factory: com.ibm.websphere.naming.WsnInitialContextFactory
   Provider URL: corbaloc:iiop:localhost:2814
   Requested root context: cell
   Starting context: (top)=ISVNKDLT0000926Node01Cell
   Formatting rules: jndi
   Time of dump: Sat Sep 26 21:08:19 AEST 2015
==============================================================================
80 (top)/nodes/ISVNKDLT0000926Node02/servers/server1/jdbc/DB2
80                                                    javax.resource.cci.ConnectionFactory

构建时增强的 OpenJPA 日志

7  DB2AccountUnit_HOGE  TRACE  [main] openjpa.Runtime - Setting the following properties from "file:/D:/Home/Workspaces/WAS/AccountDB2JPA/src/META-INF/persistence.xml" into configuration: {openjpa.ConnectionFactoryMode=managed, openjpa.ConnectionFactoryName=jdbc/DB2, openjpa.TransactionMode=managed, openjpa.MetaDataFactory=jpa(Types=sample.jpa.Db2account), openjpa.Log=File=C:/opt/openjpa/org.apache.openjpa.log, DefaultLevel=INFO, Runtime=TRACE, Tool=INFO, SQL=TRACE, JDBC=TRACE, PersistenceVersion=1.0, openjpa.Id=DB2AccountUnit_HOGE}
14  DB2AccountUnit_HOGE  TRACE  [main] openjpa.Runtime - No cache marshaller found for id org.apache.openjpa.conf.MetaDataCacheMaintenance.
55  DB2AccountUnit_HOGE  INFO   [main] openjpa.Tool - Enhancer running on type "sample.jpa.Db2account".

参考资料


更新

尝试了 IBM 红皮书 WebSphere Application 的 JPA 示例 开发人员服务器 V7。部署应用程序版本 2 并得到相同的错误。

persistence.xml 中,您必须使用资源引用,例如java:comp/env/jdbc/DB2Ref 而不是全局 JNDI 名称。并且您必须在部署描述符中或通过在使用 JPA 的 module/component 中使用名称 jdbc/DB2Ref 的注释来定义资源引用。

如果要在 persistnece.xml 中使用全局 JNDI 名称,则必须设置 Component-managed authentication alias 而不是 Container-managed,仅当通过引用访问数据源时才使用容器.

根据@Gas的回答,做了一些实验

@Servlet 中的资源和persistence.xml中的全局 JNDI

仅在 IBM WAS 的数据源设置中指定的容器管理 authentication/JAAS。
失败

[Servlet]
@WebServlet("/CreateAccount")
public class CreateAccount extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    static final long serialVersionUID = 1L;
    @Resource(name="jdbc/DB2")
    private DataSource ds;

[persistence.xml]
<persistence-unit name="DB2AccountUnitLocal" transaction-type="RESOURCE_LOCAL">
    <jta-data-source>jdbc/DB2</jta-data-source>
    <class>sample.jpa.Db2account</class>
</persistence-unit>

结果

[28/09/15 14:35:55:419 AEST] 000000f2 webapp        E com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E: [Servlet Error]-[sample.jpa.servlet.CreateAccount]: <openjpa-2.2.3-SNAPSHOT-r422266:1686911 fatal general error> org.apache.openjpa.persistence.PersistenceException: ORA-01017: invalid username/password; logon denied
 DSRA0010E: SQL State = 72000, Error Code = 1,017

@Servlet 中的资源和 persistence.xml

中的 ENC JNDI

仅在 IBM WAS 的数据源设置中指定的容器管理 authentication/JAAS。
成功

[Servlet]
@WebServlet("/CreateAccount")
public class CreateAccount extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    static final long serialVersionUID = 1L;
    @Resource(name="jdbc/DB2")
    private DataSource ds;

[persistence.xml]
<persistence-unit name="DB2AccountUnitLocal" transaction-type="RESOURCE_LOCAL">
    <jta-data-source>java:comp/env/jdbc/DB2</jta-data-source>
    <class>sample.jpa.Db2account</class>
</persistence-unit>

JDBC web.xml 中的资源引用和 persistence.xml

中的 ENC JNDI

仅在 IBM WAS 的数据源设置中指定的容器管理 authentication/JAAS。
成功

[Servlet]
@WebServlet("/CreateAccount")
public class CreateAccount extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    static final long serialVersionUID = 1L;
    //@Resource(name="jdbc/DB2")
    //private DataSource ds;

[web.xml]
<resource-ref>
  <res-ref-name>jdbc/DB2</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
</resource-ref>

[persistence.xml]
<persistence-unit name="DB2AccountUnitLocal" transaction-type="RESOURCE_LOCAL">
    <jta-data-source>java:comp/env/jdbc/DB2</jta-data-source>
    <class>sample.jpa.Db2account</class>
</persistence-unit>

组件管理的身份验证

只有组件管理的身份验证别名。映射配置别名是 DefaultPrincipalMapping。
成功

[Servlet]
@WebServlet("/CreateAccount")
public class CreateAccount extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    static final long serialVersionUID = 1L;
    //@Resource(name="jdbc/DB2")
    //private DataSource ds;

[web.xml]
  <resource-ref>
  <res-ref-name>jdbc/DB2</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
 </resource-ref>

[persistence.xml]
<persistence-unit name="DB2AccountUnitLocal" transaction-type="RESOURCE_LOCAL">
    <non-jta-data-source>jdbc/DB2</non-jta-data-source>
    <class>sample.jpa.Db2account</class>
</persistence-unit>

JPA 2.0 规范说它是要指定的数据源的全局 JNDI 名称。 IBM WAS 知识中心说 ENC 名称是 WAS 扩展。

我想由于容器管理的身份验证是通过资源引用并且 EJB3 @Resource(name) 是 ENC 名称资源引用 java:comp/env/,所以对 JPA 使用容器身份验证可能是供应商具体。

JSR 317:JavaTM 持久性 API,2.0 版最终版

8.2.1.5 jta-data-source, non-jta-data-source

In Java EE environments, the jta-data-source and non-jta-data-source elements are used to specify the global JNDI name of the JTA and/or non-JTA data source to be used by the persistence provider. If neither is specified, the deployer must specify a JTA data source at deployment or a

IBM WAS 8.5.5 Associating persistence providers and data sources

The JPA for WebSphere Application Server solution extends the JNDI data-source implementation to allow you to reference data sources in the component name space. In the EJB or web module deployment descriptor file, this is the element.

You can prefix the data source with java:comp/env/ so the application indirectly references the data source by using the local JNDI name.