【问题标题】:Is there a Spring ORM/JPA successor or alternative to TopLinkJpaVendorAdapter?是否有 Spring ORM/JPA 继任者或 TopLinkJpaVendorAdapter 的替代品?
【发布时间】:2015-04-04 18:04:03
【问题描述】:

这似乎是一个非常基本的东西,我应该能够很容易地找到它,但我一直无法找到答案!

在 Spring 3.2.4 文档中,它表明供应商对 Toplink Essentials 的支持已被删除: http://docs.spring.io/autorepo/docs/spring-framework/3.2.4.RELEASE_to_4.0.0.M3/changes/pkg_org.springframework.orm.jpa.vendor.html

但是我在任何地方都找不到使用此类的替代方法——所有使用 Spring 配置 Toplink 的示例似乎都来自 Spring 2.5 左右的时间,例如https://community.oracle.com/thread/597157

谁能告诉我现在为 Toplink JPA 实现定义 Spring 应用程序上下文的公认方法是什么?

我正在使用:

  • 弹簧 (4.1.4)
  • Toplink Essentials (2.1-60f)
  • 嵌入式 Derby DB (10.11.1.1)
  • Tomcat (8.0.18)

我当前的代码和配置设置如下所示,并且它可以工作 - 从某种意义上说,当我在我的模拟 Web 应用程序中转到 /help 时创建了数据库 - 但它不会自动创建我的实体表,这是我现在主要试图找到的解决方案。我怀疑这是因为下面定义的只是一个简单的 JDBC 数据源,而不是一个适当的 JPA 实体管理器工厂,它可以加倍努力并自动为我创建所有实体。

在我将它迁移到 WAR 并将其部署到 Tomcat 之前,我有一个独立的 java 应用程序,它使用相同的 persistence.xml,它工作得很好(自动创建数据库和实体表)。现在我已经转移到一个 Web 应用程序并将 Spring 加入其中,而不是那么多:-(

基本上,我知道我需要在我的 Spring 应用程序上下文中指定 create-tables(或 generateDdl=true),就像在 persistence.xml 文件中所做的那样,但我不确定如果没有喜欢该怎么做属于TopLinkJpaVendorAdapter 类(参见applicationContext.xml 中注释掉的元素)。

Spring 实体管理器工厂似乎引用了persistence.xml 中定义的持久性单元名称,但似乎没有注意到其中定义的任何其他内容 - 有没有办法让 Spring 接受这些persistence.xml 中定义的其他设置(即 Toplink 实体管理器工厂提供程序类和 JDBC 详细信息等)?或者,如果 Spring 放弃了供应商的实现,而直接使用 Eclipselink 或 Hibernate,是否值得继续使用 Toplink? (顺便说一句,有谁知道为什么这个实现类一开始就被删除了?)

META-INF/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 persistence_1_0.xsd">

    <persistence-unit name="xyz-jpa" transaction-type="RESOURCE_LOCAL">

        <provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>

        <class>org.xyz.MyDbEntity</class>

        <properties>
            <!--  
                <property name="toplink.jdbc.user" value="league"/>
                <property name="toplink.jdbc.password" value="league"/> 
            -->
            <property name="toplink.jdbc.url"       value="jdbc:derby:xyz;create=true"/>
            <property name="toplink.jdbc.driver"    value="org.apache.derby.jdbc.EmbeddedDriver"/>
            <property name="toplink.ddl-generation" value="create-tables"/>
        </properties>

    </persistence-unit>
</persistence>

WEB-INF/spring/applicationContext.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/mvc     http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <mvc:annotation-driven/>    
    <context:component-scan base-package="org.xyz.web" />

    <!-- <context:spring-configured /> -->
    <context:load-time-weaver aspectj-weaving="autodetect"/>

    <!--+
        | (1) Define a Spring JDBC datasource wrapper for an embedded Derby database 
        +-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
        <property name="url"             value="jdbc:derby:xyz;create=true"/>
    </bean>

    <!--+
        | (2) Define a Spring ORM entity manager factory bean wrapper for a Toplink JPA implementation 
        +-->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="xyz-jpa"/>
        <property name="dataSource"          ref="dataSource"/>
        <!--
            <property name="jpaVendorAdapter">
                <bean class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter">
                    <property name="showSql"          value="true"/>
                    <property name="generateDdl"      value="true"/>
                    <property name="databasePlatform" value="oracle.toplink.essentials.platform.database.DerbyPlatform"/>
                </bean>
            </property>

            <property name="jpaProperties">
                <props>
                    <prop key="toplink.weaving">static</prop>
                    <prop key="toplink.logging.level">FINEST</prop>
                    <prop key="toplink.ddl-generation">create-tables</prop>
                    <prop key="toplink.ddl-generation.output-mode">both</prop>
                    <prop key="toplink.drop-ddl-jdbc-file-name">generated_jpa.sql</prop>
                </props>
            </property>

            <property name="loadTimeWeaver">
                <bean class="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader" />
            </property>
        -->   
    </bean>

    <!-- (3) Define a Spring ORM transaction manager wrapper for (1) and (2) -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
        <property name="dataSource"           ref="dataSource"/>
    </bean>  


    <bean id="helpController" class="org.xyz.web.HelpController">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>


</beans>

WEB-INF/web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns="http://java.sun.com/xml/ns/javaee" 
         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
         version="2.5">

    <display-name>XYZ</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/applicationContext.xml</param-value>
    </context-param>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value> <!-- No servlet specific context config file (i.e. "dispatcher-servlet.xml") => use applicationContext.xml -->
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>  

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

</web-app>

META-INF/context.xml:

<Context path="/" reloadable="true">
    <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>

org.xyz.web.HelpController:

@RestController
public class HelpController {

    private EntityManagerFactory entityManagerFactory;

    public HelpController() {
    }   


    public EntityManagerFactory getEntityManagerFactory() {
        return entityManagerFactory;
    }


    public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
    }


    @RequestMapping( value="/help", produces=MediaType.TEXT_HTML_VALUE )
    public @ResponseBody String getHelp() {

        EntityManager entityManager = entityManagerFactory.createEntityManager();

        return "Helpy Mc Help-Help";
    }
}

【问题讨论】:

    标签: java spring-mvc jpa derby spring-orm


    【解决方案1】:

    来自 TopLink 上的Wikipedia page

    2007年,TopLink源代码捐赠给Eclipse基金会,EclipseLink项目诞生。

    因此,TopLink 的开源版本现在以 EclipseLink 的形式存在,它是 JPA 2.0 的参考实现。

    除非您有非常具体的原因使用 TopLink Essentials(这似乎不太可能,因为您使用的是 Spring 框架和 Tomcat 的最新版本),否则您应该使用其他 JPA 实现之一。

    【讨论】:

    • 感谢 manish - 我也开始接受这种观点。欣赏背景细节......从来没有想过在维基百科中寻找这种东西!不过下次会记得的。我确实注意到的一件事是 JAR 大小似乎存在巨大差异...... eclipselink.jar 约为 8.5Mb - 我猜 8 年内发生了很多事情 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-20
    • 2010-10-25
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多