Reputation: 71
This seems like it's something pretty fundamental that I should be able to find out really easily, but I have not been able to find an answer to it!
In the Spring 3.2.4 documentation, it indicates that the vendor support for Toplink Essentials has been removed: 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
But nowhere can I find what the alternative to using this class actually is - all the examples of configuring Toplink with Spring seem to be from around the time of Spring 2.5 or so, e.g. https://community.oracle.com/thread/597157
Can anyone tell me what the accepted approach for defining a spring application context for a Toplink JPA implementation now?
I'm using:
My current code and config setup is shown below, and it works - in the sense that the DB gets created when I go to /help
in my mock web application - but it doesn't create my entity tables automatically, which is what I'm mainly trying to find a solution for right now. I suspect it's because all that's defined below is a simple JDBC datasource, rather than a proper JPA entity manager factory that can go that extra mile and create all my entities for me automatically.
Before I migrated this to a WAR and deployed it to Tomcat, I had a standalone java application that used the same persistence.xml
and it worked just fine (automatically creating the database and entity tables that is). Now that I've moved to a web application and put Spring in the mix, not so much :-(
Basically, I know I need to specify create-tables
(or generateDdl=true
)somewhere in my Spring application context, like is done in the persistence.xml
file, but I'm not sure how to do that without the likes of a TopLinkJpaVendorAdapter
class (see the commented out elements in applicationContext.xml
) below.
The Spring entity manager factory seems to reference the persistence unit name defined in persistence.xml
, but doesn't seem to take notice of any the rest of what's defined in there - is there a way I can get Spring to take these other settings (i.e. Toplink entity manager factory provider class, and the JDBC details, etc.) from what's defined in persistence.xml
? Or is it even worth carrying on down the road of Toplink if Spring have dropped vendor implementations for it, and just go with Eclipselink or Hibernate instead? (As an aside, does anyone know why this implementation class was dropped in the first place?)
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";
}
}
Upvotes: 2
Views: 1080
Reputation: 20135
From the Wikipedia page on TopLink:
In 2007, TopLink source code was donated to the Eclipse Foundation and the EclipseLink project was born.
So, the open-source version of TopLink now lives on as EclipseLink, which is the reference implementation for JPA 2.0.
Unless you have a very specific reason for using TopLink Essentials (which doesn't seem likely because you are using recent versions of the Spring framework and Tomcat), you should use one of the other JPA implementations.
Upvotes: 2