是否有可能摆脱Websphere管理的DataSource的额外@Resource注释?

时间:2014-07-04 13:30:58

标签: java ejb websphere openjpa

我的EJB应用程序正在使用WebSphere 8.5中的OpenJPA持久性单元。使用以下设置在WebSphere上配置DataSource:

  • 范围:cells:pxxxxNodexxCell
  • 姓名:MYAPP_001
  • JNDI名称:jdbc / MYAPP / DS001
  • 组件管理的身份验证别名:MYAPP_001
  • Mapping-configuration别名:(无)
  • 容器管理的身份验证别名:(无)

持久性单元配置为:

<?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="myapp" transaction-type="JTA">
        <jta-data-source>java:comp/env/jdbc/MYAPP/DS001</jta-data-source>
        <class>...</class>
        <properties>
            ...
        </properties>
    </persistence-unit>
</persistence>

现在我将其导入EJB:

@PersistenceContext(name = "myapp")
private EntityManager em;

问题是,使用以下配置无法解析数据源:

  

引起:   org.apache.openjpa.persistence.ArgumentException:持久性   provider正在尝试使用persistence.xml文件中的属性   解决数据源。 Java数据库连接(JDBC)驱动程序   或者必须在中指定数据源类名   openjpa.ConnectionDriverName或javax.persistence.jdbc.driver   属性。配置中提供以下属性:   &#34; WsJpaJDBCConfigurationImpl @ 83f2eb8d:禁用PDQ:AccessIntent   任务=禁用&#34 ;.在   org.apache.openjpa.jdbc.schema.DataSourceFactory.newDataSource(DataSourceFactory.java:72)     在   org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl.createConnectionFactory(JDBCConfigurationImpl.java:849)     在   org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl.getDBDictionaryInstance(JDBCConfigurationImpl.java:602)     在   org.apache.openjpa.jdbc.meta.MappingRepository.endConfiguration(MappingRepository.java:1518)     在   org.apache.openjpa.lib.conf.Configurations.configureInstance(Configurations.java:531)     在   org.apache.openjpa.lib.conf.Configurations.configureInstance(Configurations.java:456)     在   org.apache.openjpa.lib.conf.PluginValue.instantiate(PluginValue.java:121)     在   org.apache.openjpa.conf.MetaDataRepositoryValue.instantiate(MetaDataRepositoryValue.java:68)     在   org.apache.openjpa.lib.conf.ObjectValue.instantiate(ObjectValue.java:83)     在   org.apache.openjpa.conf.OpenJPAConfigurationImpl.newMetaDataRepositoryInstance(OpenJPAConfigurationImpl.java:967)     在   org.apache.openjpa.conf.OpenJPAConfigurationImpl.getMetaDataRepositoryInstance(OpenJPAConfigurationImpl.java:958)     在   org.apache.openjpa.kernel.AbstractBrokerFactory.makeReadOnly(AbstractBrokerFactory.java:644)     在   org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:203)     在   org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:156)     在   org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:227)     在   com.ibm.ws.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:72)     在   com.ibm.ws.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:35)     在   com.ibm.ws.jpa.management.JPAEMPool.getEntityManager(JPAEMPool.java:167)     在   com.ibm.ws.jpa.management.JPATxEntityManager.getEMInvocationInfo(JPATxEntityManager.java:247)     在   com.ibm.ws.jpa.management.JPATxEntityManager.getEMInvocationInfo(JPATxEntityManager.java:179)     在   com.ibm.ws.jpa.management.JPAEntityManager.createQuery(JPAEntityManager.java:299)

我需要的是使用DataSource任何的EJB中提供EntityManager资源映射:

@Resource(name = "java:comp/env/jdbc/MYAPP/DS001", lookup = "jdbc/MYAPP/DS001", shareable = true, authenticationType = Resource.AuthenticationType.CONTAINER)
private DataSource ds;

这对我来说是非常不优雅的解决方案,因为:

  1. 这让人非常困惑。它只需要在使用@PersistenceContext的EJB的任何中声明一次。在Java代码中可能根本不使用DataSource,在我的情况下,它不会被使用。很难理解该声明在该文件中做了什么,以及为什么它只在一个文件中。

  2. 它复制了其他地方提供的配置。我需要再次指定资源的名称(它已在persistance.xml中指定)。

  3. 将配置存储在源代码中。相当肮脏的反模式。

  4. 从技术上讲,它需要来自Java 7的javax.annotation.Resource,而我的项目使用的是Java 6.但是WebSphere运行时帽改变了该注释的版本,因此一切正常,但需要使用WebSphere的javac进行编译运行时,而不是标准的JDK。

  5. 是否有可能摆脱那个注释?作为替代方案,我需要使用什么?

1 个答案:

答案 0 :(得分:2)

java:comp / env / format表示资源引用,因此必须以某种方式定义它。您有几个选项可以不定义虚拟数据源:

1.在类级别定义资源 - 这在Java 6中完全支持 - 并且它正确定义了资源引用:

@Resource(name="jdbc/dsRef", type=javax.sql.DataSource.class, lookup="jdbc/DS")
public class MyBean implements MyBeanLocal {

对此和您的代码的另一个澄清 - 在名称中,您实际上应该只提供一个引用名称(不带java:comp/env),然后在persistence.xml中放入java:comp / env / refName。 Lookup定义在服务器上注册的实际JNDI名称。您可以跳过定义查找并在安装期间或通过绑定文件绑定对资源的引用。

2.使用部署描述符

创建部署描述符(web.xml或ejb-jar.xml)并为其中的每个EJB定义资源引用。您将不再需要在类中放置带有@Resource的DataSource。

3.根本没有使用参考

虽然我不推荐它,但您可以在persistence.xml中使用实际的服务器JNDI数据源名称。然后,您不需要EJB中的DataSource,因为没有使用引用。

<jta-data-source>jdbc/MYAPP/DS001</jta-data-source>

但在这种情况下,您不会在管理控制台中看到应用程序正在使用DataSource,如果需要,您将无法将该映射更改为其他数据源jndi名称。

澄清你的评论:

  

从技术上讲,它需要来自Java 7的javax.annotation.Resource   我的项目使用的是Java 6.但是WebSphere运行时帽子已经改变了   该注释的版本,所以一切正常,但需要   使用来自WebSphere运行时的javac进行编译,而不是使用标准JDK

进行编译

javax.annotation.Resource是Java EE 6的一部分,由WebSphere实现。您不需要Java v7,但需要完全投诉Java EE 6应用程序服务器。您正在创建Java EE应用程序而不是Java SE应用程序。这就是您需要容器类来解析该注释的原因。它没有被WebSphere改变,只是遵循规范。