23

I'm reading the book "Professional Java for Web Applications - Nicholas S. Williams" The book example has this configuration for Spring Data JPA:

@Bean
public DataSource customerSupportDataSource()
{
    JndiDataSourceLookup lookup = new JndiDataSourceLookup();
    return lookup.getDataSource("jdbc/CustomerSupport");
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean()
{
    Map<String, Object> properties = new Hashtable<>();
    properties.put("javax.persistence.schema-generation.database.action",
            "none");
    properties.put("hibernate.ejb.use_class_enhancer", "true");

    HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
    adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect");

    LocalContainerEntityManagerFactoryBean factory =
            new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(adapter);
    factory.setDataSource(this.customerSupportDataSource());
    factory.setPackagesToScan("com.wrox.site.entities",
            "com.wrox.site.converters");
    factory.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE);
    factory.setValidationMode(ValidationMode.NONE);
    factory.setLoadTimeWeaver(this.loadTimeWeaver); // TODO: remove when SPR-10856 fixed
    factory.setJpaPropertyMap(properties);
    return factory;
}

@Bean
public PlatformTransactionManager jpaTransactionManager()
{
    return new JpaTransactionManager(
            this.entityManagerFactoryBean().getObject()
    );
}

But I have been configuring using XML, I cannot figure out how to translate this to XML only, I have this so far

<jee:jndi-lookup id="myDataSource" jndi-name="java:comp/env/jdbc/test"/>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="myEmf" />
</bean>

<bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="myDataSource" />
    <property name="packagesToScan" value="com.test" />
</bean>

Can any one guide me how to convert this?

Thanks

Neil Stockton
  • 11,383
  • 3
  • 34
  • 29
Navnav
  • 982
  • 3
  • 11
  • 25

2 Answers2

39

If you want to configure Spring Data JPA by using XML configuration (and use the configuration described in the book), you have to follow these steps:

  1. Configure the data source bean.
  2. Configure the entity manager factory bean.
  3. Configure the transaction manager bean.
  4. Enable annotation driven transaction management.
  5. Configure Spring Spring Data JPA.

The application context configuration (applicationContext-persistence.xml) file looks as follows:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:jpa="http://www.springframework.org/schema/data/jpa"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/data/jpa 
    http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.1.xsd">

  <!-- Configure the data source bean -->
  <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/CustomerSupport"/>

  <!-- Create default configuration for Hibernate -->
  <bean id="hibernateJpaVendorAdapter" 
    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>

  <!-- Configure the entity manager factory bean -->
  <bean id="entityManagerFactory" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter"/>
    <!-- Set JPA properties -->
    <property name="jpaProperties">
      <props>
        <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
        <prop key="javax.persistence.schema-generation.database.action">none</prop>
        <prop key="hibernate.ejb.use_class_enhancer">true</prop>
      </props>
    </property>
    <!-- Set base package of your entities -->
    <property name="packagesToScan" value="foo.bar.model"/>
    <!-- Set share cache mode -->
    <property name="sharedCacheMode" value="ENABLE_SELECTIVE"/>
    <!-- Set validation mode -->
    <property name="validationMode" value="NONE"/>
  </bean>

  <!-- Configure the transaction manager bean -->
  <bean id="transactionManager" 
    class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
  </bean>

  <!-- Enable annotation driven transaction management -->
  <tx:annotation-driven/>

  <!-- 
    Configure Spring Data JPA and set the base package of the 
    repository interfaces 
  -->
  <jpa:repositories base-package="foo.bar.repository"/>
</beans>
pkainulainen
  • 1,458
  • 1
  • 19
  • 51
  • 1
    Thanks pkainulainen, I have all the context and xml files in place. what I want is the exact translation of given java config in XML. For example for : public DataSource customerSupportDataSource() { JndiDataSourceLookup lookup = new JndiDataSourceLookup(); return lookup.getDataSource("jdbc/CustomerSupport"); } the xml would be: – Navnav Jul 31 '14 at 22:50
  • 1
    You are welcome. I updated the answer to match the configuration described in the book. I didn't test though but it should work. One thing, does the configuration class have a loadTimeWeaver field? IF it does, you should add the full Java configuration class to your question. If you do this, I can add the load time weaver to XML configuration as well. Also, please note that the XML configuration uses old schema versions. You might want to update them as well. – pkainulainen Aug 01 '14 at 18:42
  • You are right, now I need LoadTimeWeaver, but the book's source is missing that, any recommendation how to set it up? – Navnav Aug 02 '14 at 02:01
  • Sorry that took me some time to answer to this (the email got lost in my inbox). Anyway, I would just use the default LoadTimeWeaver (don't configure it). – pkainulainen Aug 16 '14 at 10:01
  • @pkainulainen I try to adapt your answer to my own problem: [Spring Data configuration - hibernate.properties not found](http://stackoverflow.com/questions/39558028/spring-data-configuration-hibernate-properties-not-found), but I am not able - is it possible to do it for embedded datasources (`jdbc:embedded-database`), not for `jee:jndi-lookup`? – Radek Anuszewski Sep 18 '16 at 14:03
  • @pkainulainen how do I specify in xml? – Naxi Apr 25 '19 at 16:10
0
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="com.thought.service.*" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="generateDdl" value="true" />
            <property name="showSql" value="false" />
            <property name="database" value="MYSQL" />
        </bean>
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
        </props>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
    
<bean id="transactionSupport" class="com.thought.service.common.database.TransactionSupport" />
        
<bean id="transactionTemplate" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="proxyInterfaces">
        <list> 
    <value>com.thought.service.common.database.TransactionTemplate</value>
        </list>
    </property>
    <!-- <property name="proxyTargetClass" value="false" />   -->
    <property name="transactionManager" ref="transactionManager" />
    <property name="target" ref="transactionSupport" />
    <property name="transactionAttributes">
        <props>
            <prop key="save">PROPAGATION_REQUIRES_NEW,-java.lang.Exception</prop>
        </props>
    </property>
</bean>
public class TransactionSupport implements TransactionTemplate {
    
    public void save(PersistenceHandler persistanceHandler, ModelTemplate model) throws Exception {
        persistanceHandler.save(model);
    }
    
}
public interface TransactionTemplate {
    
    public void save(PersistenceHandler persistanceHandler, ModelTemplate model) throws Exception;
            
}
public abstract class PersistenceHandler {
        
    /**
     * Method to implement the actual transaction controlled database operations
     * @param model {@code ModelTemplate}
     * 
     * @throws Exception
     */
    public abstract void save(ModelTemplate model) throws Exception;
                
}
zdadco
  • 102
  • 9