persistence with spring ebook

Upload: pratik-shah

Post on 02-Jun-2018

260 views

Category:

Documents


1 download

TRANSCRIPT

  • 8/10/2019 Persistence With Spring eBook

    1/45

    1

    PERSISTENCE WITH SPRING

    TABLE OF CONTENTS

    1. Spring with Maven

    2. Hibernate 3 with Spring

    3. Hibernate 4 with Spring

    4. Spring 3 and JPA with Hibernate

    5. The Persistence Layer with Spring Data JPA

    6. The DAO with Spring 3 and Hibernate

    7. The DAO with JPA and Spring

    8. Simplify the DAO with Spring and Java Generics

    9. Transactions with Spring 3 and JPA

  • 8/10/2019 Persistence With Spring eBook

    2/45

    2

    Spring with Maven

    1. Overview

    2. Basic Maven Spring Dependencies

    3. Spring Persistence with Maven

    4. Spring MVC with Maven

    5. Spring Security with Maven

    6. Spring Test

    7. Using Milestones

    8. Using Snapshots

    9. Conclusion

    Hibernate 3 with Spring

    1. Overview

    2. Java Spring Configuration for Hibernate 3

    3. XML Spring Configuration for Hibernate 3

    4. Spring, Hibernate and MySQL

    5. Usage

    6. Maven

    7. Conclusion

    Hibernate 4 with Spring

    1. Overview

    2. Maven

    3. Java Spring Configuration for Hibernate 4

    4. XML Spring Configuration for Hibernate 4

    5. Spring, Hibernate and MySQL

  • 8/10/2019 Persistence With Spring eBook

    3/45

    3

    6. Usage

    7. Conclusion

    Spring 3 and JPA with Hibernate

    1. Overview

    2. The JPA Spring Configuration with Java

    3. The JPA Spring Configuration with XML

    4. Going full XML-less

    5. The Maven configuration

    6. Conclusion

    The Persistence Layer with Spring Data JPA

    1. Overview

    2. No More DAO implementations

    3. The Spring Data managed DAO

    4. Defining custom access method and queries

    5. Spring Data transaction configuration

    6. Spring Data Configuration

    7. The Spring Java or XML configuration

    8. The Maven configuration

    9. Conclusion

    The DAO with Spring 3 and Hibernate

    1. Overview

    2. No More Spring Templates

    3. The DAO

  • 8/10/2019 Persistence With Spring eBook

    4/45

    4

    4. Conclusion

    The DAO with JPA and Spring

    1. Overview

    2. No More Spring Templates

    3. The DAO

    4. Conclusion

    Simplify the DAO with Spring and Java Generics

    1. Overview

    2. The Hibernate and JPA DAOs

    3. Injecting this DAO

    4. Conclusion

    Transactions with Spring 3 and JPA

    1. Overview

    2. Configure Transactions without XML

    3. Configure Transactions with XML

    4. The @TransactionalAnnotation

    5. Potential Pitfalls

    6. Conclusion

  • 8/10/2019 Persistence With Spring eBook

    5/45

    5

    Spring with Maven

    1. Overview

    This sectionwill discuss how to setup Spring with Mavenand will go over specificusecases of using Spring dependencies. The latest Spring releases can be foundonMaven Central.

    2. Basic Maven Spring Dependencies

    Spring was designed to be modular and flexible the basic Spring container can beused in a variety of scenarios, without including any of the more advanced functionalitythat the framework has to offer. A very basic Maven setup will only have to use thespring-contextdependency:

    3.2.5.RELEASE

    org.springframework

    spring-context${org.springframework.version}

    runme

    This dependency spring-context defines the actual Spring Injection Container andhas a small number of dependencies: spring-core, spring-expression, spring-aopandspring-beans. These augment the container by enabling support for some of the coreSpring technologies: the Core Spring utilities, the Spring Expression Language(SpEL), theAspect Oriented Programmingsupport and the JavaBeans mechanism.

    Note the runtimescopeis used when defining the spring-contextdependency thiswill make sure that there are no compile time dependencies on any Spring specific APIs.For more advanced usecases the runtimescope may be removed from some selectedSpring dependencies, but for simpler projects, there is no need to compile againstSpringto make full use of the framework.

    Also note that, starting with Spring 3.2, the CGLIB dependnecy(now upgraded toCGLIB 3.0) has been repackaged (the all net.sf.cglib package is now

    http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.springframework%22http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.springframework%22http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.springframework%22http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/expressions.htmlhttp://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/aop.html#aop-introductionhttp://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-definitionhttp://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-definitionhttp://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/aop.html#aop-introductionhttp://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/expressions.htmlhttp://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.springframework%22http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.springframework%22
  • 8/10/2019 Persistence With Spring eBook

    6/45

    6

    org.springframework.cglib) and inlined directly within the spring-core JAR (see the JIRAfor additional details), so there is no need to define it explicitly.

    3. Spring Persistence with Maven

    In addition to the core Spring dependencies shown above, the principal Springpersistence dependency is spring-orm:

    org.springframework

    spring-orm

    ${org.springframework.version}

    This brings in Hibernate and JPA support such as HibernateTemplateand JpaTemplate as well as the a few additional, persistence related dependencies: spring-jdbcandspring-tx. The JDBC Data Access library defines the Spring JDBC supportas well as theJdbcTemplate, and spring-txrepresents the extremely flexible Transaction Management

    Abstractionin Spring.

    4. Spring MVC with Maven

    To use the Spring Web and Servlet support, there are two dependencies that need to beincluded in the pom, again in addition to the core dependencies from above:

    org.springframework

    spring-web

    ${org.springframework.version}

    org.springframework

    spring-webmvc

    ${org.springframework.version}

    The spring-webdependency contains common web specific utilities for both Servlet andPortlet environments, while spring-webmvcenables the MVC supportfor Servletenvironments. Since spring-webmvchas spring-webas a dependency, explicitly definingspring-webis not required when using spring-webmvc.

    http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/transaction.htmlhttp://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/transaction.htmlhttp://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/jdbc.htmlhttps://jira.springsource.org/browse/SPR-9669
  • 8/10/2019 Persistence With Spring eBook

    7/45

    7

    5. Spring Security with Maven

    Security Maven dependenciesare discussed in depth in the Spring Security withMavenarticle.

    6. Spring Test

    The Spring Test Framework can be included in the project via the followingdependency:

    org.springframework

    spring-test

    ${spring.version}

    test

    As of Spring 3.2, the Spring MVC Test project, which started as a standalone projectavailable on github, has been included into the core Test Framework; this means thatSpring 3.2 applications should simply use the spring-testdependency.

    For applications still using Spring 3.1 and below, the older standalone Mavendependency still exists and can be usedfor almost identical results. The dependency isnot on Maven Central however, so using it will require adding a custom repository to thepom of the project.

    7. Using Milestones

    The release version of Spring are hosted on Maven Central. However, if a project needsto use milestone versions, then a custom Spring repository needs to be added to thepom:

    repository.springframework.maven.milestone

    Spring Framework Maven Milestone Repository

    hp://maven.springframework.org/milestone

    http://maven.springframework.org/milestonehttps://github.com/SpringSource/spring-test-mvc#readmehttps://github.com/SpringSource/spring-test-mvchttp://www.baeldung.com/spring-security-with-mavenhttp://www.baeldung.com/spring-security-with-maven
  • 8/10/2019 Persistence With Spring eBook

    8/45

    8

    One this repository has been defined, the project can define dependencies such as:

    org.springframework

    spring-core

    3.2.0.RC2

    8. Using Snapshots

    Similar to milestons, snapshots are hosted in a custom repository:

    repository.springframework.maven.snapshot

    Spring Framework Maven Snapshot Repository hp://maven.springframework.org/snapshot

    Once the SNAPSHOT repository is enabled in the pom, the following dependencies canbe referenced:

    org.springframework

    spring-core

    3.3.0.BUILD-SNAPSHOT

    And even:

    org.springframework

    spring-core

    4.4.0.BUILD-SNAPSHOT

    9. Conclusion

    This section discusses the practical details of using Spring with Maven. The Mavendependencies presented here are of course some of the major ones, and there areseveral others that may be worth mentioning and have not yet made the cut.Nevertheless this should be a good starting point for using Spring in a project.

    http://maven.springframework.org/snapshot
  • 8/10/2019 Persistence With Spring eBook

    9/45

    9

    Hibernate 3 with Spring

    1. Overview

    Lets jump straight into our first practical usecase - for this section, well focus onsetting up Hibernate 3 with Spring. Well look at how to use both XML and Javaconfiguration to set up Spring 3 with Hibernate 3 and MySQL.

    2. Java Spring Configuration for Hibernate 3

    Setting up Hibernate 3 with Spring and Java config is straightforward:

    import java.ul.Properes;

    import javax.sql.DataSource;

    import org.apache.tomcat.dbcp.dbcp.BasicDataSource;

    import org.springframework.beans.factory.annotaon.Autowired;

    import org.springframework.context.annotaon.Bean;

    import org.springframework.context.annotaon.ComponentScan;

    import org.springframework.context.annotaon.Configuraon;

    import org.springframework.context.annotaon.PropertySource;

    import org.springframework.core.env.Environment;

    import org.springframework.dao.annotaon.PersistenceExceponTranslaonPostProcessor;

    import org.springframework.orm.hibernate3.HibernateTransaconManager;

    import org.springframework.orm.hibernate3.annotaon.AnnotaonSessionFactoryBean;

    import org.springframework.transacon.annotaon.EnableTransaconManagement;

    import com.google.common.base.Precondions;

    @Configuraon

    @EnableTransaconManagement

    @PropertySource({ "classpath:persistence-mysql.properes" })

    @ComponentScan({ "org.baeldung.spring.persistence" })

    public classPersistenceConfig {

    @Autowired

    privateEnvironment env;

    @Bean

    publicAnnotaonSessionFactoryBean sessionFactory() {

    AnnotaonSessionFactoryBean sessionFactory = new AnnotaonSessionFactoryBean();

    sessionFactory.setDataSource(restDataSource());

  • 8/10/2019 Persistence With Spring eBook

    10/45

    10

    sessionFactory.setPackagesToScan(newString[] { "org.baeldung.spring.persistence.model"

    });

    sessionFactory.setHibernateProperes(hibernateProperes());

    returnsessionFactory;

    }

    @Bean

    public DataSource restDataSource() {

    BasicDataSource dataSource = newBasicDataSource();

    dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));

    dataSource.setUrl(env.getProperty("jdbc.url"));

    dataSource.setUsername(env.getProperty("jdbc.user"));

    dataSource.setPassword(env.getProperty("jdbc.pass"));

    returndataSource;

    }

    @Bean

    @Autowired

    publicHibernateTransaconManager transaconManager(SessionFactory sessionFactory) {

    HibernateTransaconManager txManager = newHibernateTransaconManager();

    txManager.setSessionFactory(sessionFactory);

    returntxManager;

    }

    @Bean

    publicPersistenceExceponTranslaonPostProcessor exceponTranslaon() { return newPersistenceExceponTranslaonPostProcessor();

    }

    Properes hibernateProperes() {

    return newProperes() {

    {

    setProperty("hibernate.hbm2ddl.auto",

    env.getProperty("hibernate.hbm2ddl.auto"));

    setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));

    }

    };

    }

    }

    Compared to the XML Configuration described next there is a small difference in theway one bean in the configuration access another. In XML there is no differencebetween pointing to a bean or pointing to a bean factory capable of creatingthat bean. Since the Java configuration is type-safe pointing directly to the bean

  • 8/10/2019 Persistence With Spring eBook

    11/45

    11

    factory is no longer an option we need to retrieve the bean from the bean factorymanually:

    txManager.setSessionFactory(sessionFactory().getObject());

    3. XML Spring Configuration for Hibernate 3

    Similarly, we can set upHibernate 3 with XML configas well:

    ${hibernate.hbm2ddl.auto}

    ${hibernate.dialect}

    http://www.springframework.org/schema/context/spring-context-3.2.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/contexthttp://www.w3.org/2001/XMLSchema-instancehttp://www.springframework.org/schema/beans
  • 8/10/2019 Persistence With Spring eBook

    12/45

    12

    Then, this XML file is bootstrapped into the Spring context using a @Configurationclass:

    @Configuraon

    @EnableTransaconManagement

    @ImportResource({ "classpath:persistenceConfig.xml" })

    public classPersistenceXmlConfig {

    //

    }

    For both types of configuration, the JDBC and Hibernate specific properties are stored ina properties file:

    # jdbc.X

    jdbc.driverClassName=com.mysql.jdbc.Driver

    jdbc.url=jdbc:mysql://localhost:3306/spring_hibernate_dev?createDatabaseIfNotExist=true

    jdbc.user=tutorialuser

    jdbc.pass=tutorialmy5ql

    # hibernate.X

    hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

    hibernate.show_sql=false

    hibernate.hbm2ddl.auto=create-drop

    4. Spring, Hibernate and MySQL

    The example above uses MySQL 5 as the underlying database configured withHibernate however, Hibernate supports several underlying SQL Databases.

    4.1. The DriverThe Driver class name is configured via the jdbc.driverClassNamepropertyprovided to the DataSource.

    In the example above, it is set to com.mysql.jdbc.Driverfrom the mysql-connector-javadependency we defined in the pom, at the start of the section.

    https://community.jboss.org/wiki/SupportedDatabases2
  • 8/10/2019 Persistence With Spring eBook

    13/45

    13

    4.2. The Dialect

    The Dialect is configured via the hibernate.dialectpropertyprovided to the

    Hibernate SessionFactory.

    In the example above, this is set to org.hibernate.dialect.MySQL5Dialectas we areusing MySQL 5 as the underlying Database. There are several other dialectssupporting MySQL:

    org.hibernate.dialect.MySQL5InnoDBDialect for MySQL 5.x with theInnoDB storage engine

    org.hibernate.dialect.MySQLDialect for MySQL prior to 5.x org.hibernate.dialect.MySQLInnoDBDialect for MySQL prior to 5.x with

    the InnoDB storage engine

    org.hibernate.dialect.MySQLMyISAMDialect for all MySQL versions withthe ISAM storage engine

    Hibernate supports SQL Dialectsfor every supported Database.

    5. Usage

    At this point, Hibernate 3 is fully configured with Spring and we caninject the rawHibernateSessionFactorydirectly whenever we need to:

    public abstract classFooHibernateDAO{

    @Autowired

    SessionFactory sessionFactory;

    ...

    protectedSession getCurrentSession(){

    returnsessionFactory.getCurrentSession();

    }

    }

    6. Maven

    To add the Spring Persistence dependencies to the pom, please see the >> Spring withMaven example well need to define both spring-contextand spring-orm.

    http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/session-configuration.html#configuration-optional-dialects
  • 8/10/2019 Persistence With Spring eBook

    14/45

    14

    Continuing to Hibernate 3, the Maven dependencies are simple:

    org.hibernate

    hibernate-core

    3.6.10.Final

    Then, to enable Hibernate to use its proxy model, we needjavassistas well:

    org.javassist

    javassist

    3.18.1-GA

    Were going to use MySQL as our DB for this section, so well also need:

    mysql

    mysql-connector-java

    5.1.28

    runme

    And finally, we will not be using the Spring datasource implementation theDriverManagerDataSource; instead well use a production ready connection poolsolution Tomcat JDBC Connection Pool:

    org.apache.tomcat

    tomcat-dbcp

    7.0.47

    7. Conclusion

    In this example, we configured Hibernate 3 with Spring both with Java and XMLconfiguration. The implementation of this simple project can be found in the githubproject this is an Eclipse based project, so it should be easy to import and run as it is.

    https://github.com/eugenp/tutorials/tree/master/spring-hibernate3#readmehttps://github.com/eugenp/tutorials/tree/master/spring-hibernate3#readmehttps://github.com/eugenp/tutorials/tree/master/spring-hibernate3#readmehttps://github.com/eugenp/tutorials/tree/master/spring-hibernate3#readme
  • 8/10/2019 Persistence With Spring eBook

    15/45

    15

    Hibernate 4 with Spring

    1. Overview

    Now that we have seen how to set up the older Hibernate 3 with Spring, lets see howto do the same with Hibernate 4. Well look at how to configure Spring 3 withHibernate 4 using both Java and XML Configuration. Parts of this process are of coursecommon to the previous section.

    2. MavenTo add the Spring Persistence dependencies to the project pom.xml, feel free to jumpback to the first section of this eBook:>> Spring with Maven

    Continuing with Hibernate 4, the Maven dependencies are simple:

    org.hibernate

    hibernate-core

    4.3.0.Final

    Then, to enable Hibernate to use its proxy model, we need javassist as well:

    org.javassist

    javassist

    3.18.1-GA

    And since were going to use MySQL for thissection, well also need:

    mysql

    mysql-connector-java

    5.1.28

    runme

  • 8/10/2019 Persistence With Spring eBook

    16/45

    16

    And finally, we are using a proper connection poolinstead of the dev-only Springimplementation the DriverManagerDataSource. Were using here the Tomcat JDBCConnection Pool:

    org.apache.tomcat tomcat-dbcp

    7.0.47

    3. Java Spring Configuration for Hibernate 4

    To use Hibernate 4 in a project, a few things have changed on the configuration sidewhen moving from a Hibernate 3 setup.

    The main aspect that is different when upgrading from Hibernate 3 is the way to createthe SessionFactorywith Hibernate 4.

    This is now done by using the LocalSessionFactoryBeanfrom the hibernate4package which replaces the older AnnotationSessionFactoryBeanfrom the hibernate3package. The new FactoryBeanhas the same responsibility it bootstraps theSessionFactoryfrom annotation scanning. This is neccessary because, starting withHibernate 3.6, the oldAnnotationConfigurationwas mergedinto Configurationand sothe new Hibernate 4 LocalSessionFactoryBeanis using this new Configurationmechanism.

    It is also worth noting that, in Hibernate 4, the Configuration.buildSessionFactorymethod and mechanism have also been deprecatedin favourofConfiguration.buildSessionFactory(ServiceRegistry) which theSpring LocalSessionFactoryBeanis not yet using.

    The Spring Java Configuration for Hibernate 4:

    importjava.ul.Properes;

    importjavax.sql.DataSource;

    importorg.hibernate.SessionFactory;

    import org.apache.tomcat.dbcp.dbcp.BasicDataSource;

    importorg.springframework.beans.factory.annotaon.Autowired; importorg.springframework.context.annotaon.Bean;

    importorg.springframework.context.annotaon.ComponentScan;

    importorg.springframework.context.annotaon.Configuraon;

    importorg.springframework.context.annotaon.PropertySource;

    importorg.springframework.core.env.Environment;

    importorg.springframework.dao.annotaon.PersistenceExceponTranslaonPostProcessor;

    importorg.springframework.orm.hibernate4.HibernateTransaconManager;

    http://stackoverflow.com/questions/8621906/is-buildsessionfactory-deprecated-in-hibernate-4https://hibernate.atlassian.net/browse/HHH-5991https://hibernate.atlassian.net/browse/HHH-5375http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.htmlhttp://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html
  • 8/10/2019 Persistence With Spring eBook

    17/45

    17

    importorg.springframework.orm.hibernate4.LocalSessionFactoryBean;

    importorg.springframework.transacon.annotaon.EnableTransaconManagement;

    importcom.google.common.base.Precondions;

    @Configuraon

    @EnableTransaconManagement

    @PropertySource({ "classpath:persistence-mysql.properes" })

    @ComponentScan({ "org.baeldung.spring.persistence" })

    public classPersistenceConfig {

    @Autowired

    privateEnvironment env;

    @Bean

    publicLocalSessionFactoryBean sessionFactory() {

    LocalSessionFactoryBean sessionFactory =new LocalSessionFactoryBean();

    sessionFactory.setDataSource(restDataSource());

    sessionFactory.setPackagesToScan(newString[] {"org.baeldung.spring.persistence.model"});

    sessionFactory.setHibernateProperes(hibernateProperes());

    returnsessionFactory;

    }

    @Bean

    publicDataSource restDataSource() {

    BasicDataSource dataSource =newBasicDataSource();

    dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));

    dataSource.setUrl(env.getProperty("jdbc.url")); dataSource.setUsername(env.getProperty("jdbc.user"));

    dataSource.setPassword(env.getProperty("jdbc.pass"));

    returndataSource;

    }

    @Bean

    @Autowired

    public HibernateTransaconManager transaconManager(SessionFactory sessionFactory) {

    HibernateTransaconManager txManager = newHibernateTransaconManager();

    txManager.setSessionFactory(sessionFactory);

    returntxManager;

    }

    @Bean

    publicPersistenceExceponTranslaonPostProcessor exceponTranslaon() {

    return new PersistenceExceponTranslaonPostProcessor();

    }

  • 8/10/2019 Persistence With Spring eBook

    18/45

    18

    Properes hibernateProperes() {

    return newProperes() {

    {

    setProperty("hibernate.hbm2ddl.auto",

    env.getProperty("hibernate.hbm2ddl.auto"));

    setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));

    setProperty("hibernate.globally_quoted_idenfiers", "true");

    }

    };

    }

    }

    4. XML Spring Configuration for Hibernate 4

    Simillary, Hibernate 4 can be configured with XMLas well:

    ${hibernate.hbm2ddl.auto}

    ${hibernate.dialect}

    http://www.springframework.org/schema/context/spring-context-3.2.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/contexthttp://www.w3.org/2001/XMLSchema-instancehttp://www.springframework.org/schema/beans
  • 8/10/2019 Persistence With Spring eBook

    19/45

    19

    To bootstrap the XML into the Spring Context, we can use a simple Java Configurationfile if the application is configured with Java configuration:

    @Configuraon

    @EnableTransaconManagement

    @ImportResource({ "classpath:hibernate4Config.xml" })

    public class HibernateXmlConfig{

    //

    }

    Alternatively we can simply provide the XML file to the Spring Context, if the overallconfiguration is purely XML.

    For both types of configuration, the JDBC and Hibernate specific properties are stored in

    a properties file:

    # jdbc.X

    jdbc.driverClassName=com.mysql.jdbc.Driver

    jdbc.url=jdbc:mysql://localhost:3306/spring_hibernate_dev?createDatabaseIfNotExist=true

    jdbc.user=tutorialuser

    jdbc.pass=tutorialmy5ql

    # hibernate.X

    hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

    hibernate.show_sql=false

    hibernate.hbm2ddl.auto=create-drop

    5. Spring, Hibernate and MySQL

    The Drivers and Dialects supported by Hibernate >> have been extensively discussedfor Hibernate 3 and everything still applies for Hibernate 4 as well.

  • 8/10/2019 Persistence With Spring eBook

    20/45

    20

    6. Usage

    At this point, Hibernate 4 is fully configured with Spring and we can inject the rawHibernate SessionFactorydirectly whenever we need to:

    public abstract classBarHibernateDAO{

    @Autowired

    SessionFactory sessionFactory;

    ...

    protectedSession getCurrentSession(){

    returnsessionFactory.getCurrentSession();

    } }

    An important note here is that this is now the recommended way to use the HibernateAPI the older HibernateTemplateis no longer included in the neworg.springframework.orm.hibernate4package as it shouldnt be used with Hibernate 4.

    7. Conclusion

    In this example, we configured Spring with Hiberate 4 both with Java and XMLconfiguration.

    The implementation of this simple project can be found in the github project this is anEclipse based project, so it should be easy to import and run as it is.

    https://github.com/eugenp/tutorials/tree/master/spring-hibernate4#readme
  • 8/10/2019 Persistence With Spring eBook

    21/45

    21

    Spring 3 and JPA with Hibernate

    1. Overview

    This sectionshows how to set up Spring with JPA, using Hibernate as a persistenceprovider.

    For a step by step introduction about setting up the Spring context using Java basedconfiguration and the basic Maven pom for the project, see this article.

    2. The JPA Spring Configuration with Java

    To use JPA in a Spring project, the EntityManagerneeds to be set up.

    This is the main part of the configuration and it is done via a Spring factory bean either the simpler LocalEntityManagerFactoryBeanor the more flexibleLocalContainerEntityManagerFactoryBean. The latter option is used here, so thatadditional properties can be configured on it:

    @Configuraon

    @EnableTransaconManagementpublic classPersistenceJPAConfig{

    @Bean

    publicLocalContainerEntyManagerFactoryBean entyManagerFactoryBean() {

    LocalContainerEntyManagerFactoryBean em = new

    LocalContainerEntyManagerFactoryBean();

    em.setDataSource(dataSource());

    em.setPackagesToScan(newString[] { "org.baeldung.persistence.model" });

    JpaVendorAdapter vendorAdapter = newHibernateJpaVendorAdapter();

    em.setJpaVendorAdapter(vendorAdapter);

    em.setJpaProperes(addionalProperes());

    returnem;

    }

    @Bean

    publicDataSource dataSource(){

    DriverManagerDataSource dataSource = new DriverManagerDataSource();

    http://www.baeldung.com/2011/10/20/bootstraping-a-web-application-with-spring-3-1-and-java-based-configuration-part-1/http://www.baeldung.com/2011/10/20/bootstraping-a-web-application-with-spring-3-1-and-java-based-configuration-part-1/
  • 8/10/2019 Persistence With Spring eBook

    22/45

    22

    dataSource.setDriverClassName("com.mysql.jdbc.Driver");

    dataSource.setUrl("jdbc:mysql://localhost:3306/spring_jpa");

    dataSource.setUsername( "tutorialuser" );

    dataSource.setPassword( "tutorialmy5ql" );

    returndataSource;

    }

    @Bean

    publicPlaormTransaconManager transaconManager(EntyManagerFactory emf){

    JpaTransaconManager transaconManager = new JpaTransaconManager();

    transaconManager.setEntyManagerFactory(emf);

    returntransaconManager;

    }

    @Bean

    publicPersistenceExceponTranslaonPostProcessor exceponTranslaon(){

    return newPersistenceExceponTranslaonPostProcessor();}

    Properes addionalProperes() {

    return new Properes() {

    { // Hibernate Specific:

    setProperty("hibernate.hbm2ddl.auto", "create-drop");

    setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");

    }

    };

    }

    }

    Also, note that, before Spring 3.2, cglibhad to be on the classpath for Java@Configurationclasses to work; to better understand the need for cglibas adependency, see this discussion about the cglib artifact in Spring.

    3. The JPA Spring Configuration with XML

    The same Spring Configuration with XML:

  • 8/10/2019 Persistence With Spring eBook

    23/45

    23

    hp://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

    create-drop

    org.hibernate.dialect.MySQL5Dialect

    There is a relatively small difference between the way Spring is configured in XML andthe new Java based configuration in XML, a reference to another bean can point to

    either the bean or a bean factory for that bean. In Java however, since the types aredifferent, the compiler doesnt allow it, and so the EntityManagerFactory is firstretrieved from its bean factory and then passed to the transaction manager:

    txManager.setEntityManagerFactory(this.entityManagerFactoryBean().getObject());

    http://www.springframework.org/schema/tx/spring-tx-3.2.xsdhttp://mysql//localhost:3306/spring_jpahttp://mysql//localhost:3306/spring_jpahttp://www.springframework.org/schema/tx/spring-tx-3.2.xsd
  • 8/10/2019 Persistence With Spring eBook

    24/45

    24

    4. Going full XML-less

    Usually JPA defines a persistence unit through the META-INF/persistence.xmlfile.Starting with Spring 3.1, the persistence.xmlis no longer necessary theLocalContainerEntityManagerFactoryBeannow supports a packagesToScanproperty

    where the packages to scan for @Entityclasses can be specified.

    This file was the last piece of XML to be removed now, JPA can be fully set up withno XML.

    4.1. The JPA Properties

    JPA properties would usually be specified in the persistence.xmlfile; alternatively, theproperties can be specified directly to the entity manager factory bean:

    factoryBean.setJpaProperties( this.additionalProperties() );

    As a side-note, if Hibernate would be the persistence provider, then this would be theway to specify Hibernate specific properties.

    5. The Maven configuration

    In addition to Spring Core and persistence dependencies show in detail in the>>

    Spring with Maven section we also need to define JPA and Hibernate in the project,

    as well as a MySQL connector:

    org.hibernate

    hibernate-entymanager

    4.2.8.Final

    runme

    mysql

    mysql-connector-java

    5.1.27

    runme

    Note that the MySQL dependency is included as a reference a driver is needed toconfigure the datasource, but any Hibernate supported databasewill do.

    http://community.jboss.org/wiki/SupportedDatabases2http://community.jboss.org/wiki/SupportedDatabases2
  • 8/10/2019 Persistence With Spring eBook

    25/45

    25

    6. Conclusion

    This sectionillustrated how to configure JPA with Hibernate in Springusing bothXML and Java configuration.

    We also discussed how to get rid of the last piece of XML usually associated with JPA the persistence.xml. The final result is a lightweight, clean DAO implementation, withalmost no compile-time reliance on Spring.

    The implementation of this Spring JPA Sectioncan be found in the github project thisis an Eclipse based project, so it should be easy to import and run as it is.

    https://github.com/eugenp/tutorials/tree/master/spring-jpa#readmehttps://github.com/eugenp/tutorials/tree/master/spring-jpa#readme
  • 8/10/2019 Persistence With Spring eBook

    26/45

    26

    The Persistence Layer with SpringData JPA

    1. Overview

    This section will focus on the configuration and implementation of the persistence layerwith Spring 3.1, JPA and Spring Data. For a step by step introduction about settingup the Spring context using Java based configuration and the basic Maven pom for theproject, see this article.

    2. No More DAO implementations

    As we will discuss in a later section, >> the DAO layer usually consists of a lot ofboilerplate code that can and should be simplified. The advantages of such asimplification are many fold: a decrease in the number of artifacts that need to bedefined and maintained, simplification and consistency of data access patterns andconsistency of configuration.

    Spring Data takes this simplification one step forward and makes it possible to remove

    the DAO implementations entirely the interface of the DAO is now the onlyartifact that need to be explicitly defined.

    3. The Spring Data managed DAO

    In order to start leveraging the Spring Data programming model with JPA, a DAOinterface needs to extend the JPA specific Repositoryinterface - JpaRepository inSprings interface hierarchy. This will enable Spring Data to find this interface and

    automatically create an implementation for it.

    Also, by extending the interface we get most if not all relevant CRUD generic methodsfor standard data access available in the DAO.

    http://www.baeldung.com/2011/10/20/bootstraping-a-web-application-with-spring-3-1-and-java-based-configuration-part-1/
  • 8/10/2019 Persistence With Spring eBook

    27/45

    27

    4. Defining custom access method and queries

    As discussed, by implementing one of the Repositoryinterfaces, the DAO will alreadyhave some basic CRUD methods (and queries) defined and implemented. To definemore specific access methods, Spring JPA supports quite a few options you can either

    simplydefine a new methodin the interface, or you can provide the actual JPQqueryby using the @Queryannotation.

    A third option to define custom queries is to make use of JPA Named Queries, but thishas the disadvantage that it either involves XML or burdening the domain class with thequeries.

    In addition to these, Spring Data introducesa more flexible and convenient API, similarto the JPA Criteria API, only more readable and reusable. The advantages of this APIwill become more pronounced when dealing with a large number of fixed queries thatcould potentially be more concisely expressed through a smaller number of reusableblocks that keep occurring in different combinations.

    4.1. Automatic Custom Queries

    When Spring Data creates a new Repositoryimplementation, it analyses all themethods defined by the interfaces and tries to automatically generate queries from themethod name. While this has limitations, it is a very powerful and elegant way ofdefining new custom access methods with very little effort.

    For example, if the managed entity has a name field (and the Java Bean standardgetter and setter for that field), defining the findByNamemethodin the DAOinterface will automatically generate the correct query:

    publicinterface IFooDAO extendsJpaRepository< Foo, Long >{

    Foo findByName( final Stringname );

    }

    This is a relatively simple example; a much larger set of keywordsis supported byquery creation mechanism.

    In the case that the parser cannot match the property with the domain object field, thefollowing exception is thrown:

    Java.lang.IllegalArgumentException: No property namfound for type classorg.rest.model.Foo

    http://static.springsource.org/spring-data/data-jpa/docs/1.1.x/reference/html/#jpa.query-methods.query-creationhttp://blog.springsource.org/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/
  • 8/10/2019 Persistence With Spring eBook

    28/45

    28

    4.2. Manual Custom Queries

    In addition to deriving the query from the method name, a custom query can be

    manually specified with the method level @Queryannotation.

    For even more fine grained control over the creation of queries, such as using namedparameters or modifying existing queries, the referenceis a good place to start.

    5. Spring Data transaction configuration

    The actual implementation of the Spring Data managed DAO SimpleJpaRepositoryuses annotations to define and configure transactions. A read only @Transactionalannotation is used at the class level, which is then overridden for the non read-onlymethods. The rest of the transaction semantics are default, but these can be easilyoverridden manually per method.

    5.1. Exception Translation without the template

    One of the responsibilities of Spring ORM templates (JpaTemplate, HibernateTemplate)is exception translation translating JPA exceptions which tie the API to JPA to

    Springs DataAccessExceptionhierarchy.

    Without the template to do that, exception translation can still be enabled byannotating the DAOs with the @Repositoryannotation. That, coupled with a Springbean postprocessor will advice all @Repositorybeans with all the implementations ofPersistenceExceptionTranslatorfound in the Container to provide exception translationwithout using the template.

    The fact that exception translation is indeed active can easily be verified with anintegration test:

    @Test( expected = DataAccessExcepon.class )

    public void whenAUniqueConstraintIsBroken_thenSpringSpecificExceponIsThrown(){

    String name = "randomName";

    service.save( newFoo( name ) );

    service.save( newFoo( name ) );

    }

    Exception translation is done through proxies; in order for Spring to be able to create

    http://static.springsource.org/spring-data/data-jpa/docs/1.1.x/reference/html/#jpa.named-parameters
  • 8/10/2019 Persistence With Spring eBook

    29/45

    29

    proxies around the DAO classes, these must not be declared final.

    6. Spring Data Configuration

    To activate the Spring JPA repository support, the jpanamespaceis defined and usedto specify the package where to DAO interfaces are located:

    At this point, there is no equivalent Java based configuration support for it is howeverin the works.

    7. The Spring Java or XML configuration

    The previous section of the series already discussed in great detail how to >> configureJPA in Spring 3. Spring Data also takes advantage of the Spring support for the JPA@PersistenceContextannotation which it uses to wire the EntityManagerinto the Springfactory bean responsible with creating the actual DAO implementations JpaRepositoryFactoryBean.

    In addition to the already discussed configuration, there is one last missing piece

    including the Spring Data XML configuration in the overall persistence configuration:

    @Configuraon

    @EnableTransaconManagement

    @ImportResource( "classpath*:*springDataConfig.xml" )

    public classPersistenceJPAConfig{

    ...

    }

    https://jira.springsource.org/browse/DATAJPA-69http://www.springframework.org/schema/data/jpa/spring-jpa.xsdhttp://www.springframework.org/schema/data/jpahttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/data/jpahttp://www.w3.org/2001/XMLSchema-instancehttp://www.springframework.org/schema/beans
  • 8/10/2019 Persistence With Spring eBook

    30/45

    30

    8. The Maven configuration

    In addition to the Maven configuration for JPA defined in a >> previous section thespring-data-jpadependency is added:

    org.springframework.data

    spring-data-jpa

    1.4.3.RELEASE

    9. Conclusion

    This section covered the configuration and implementation of the persistence layer withSpring 3.1, JPA 2 and Spring JPA (part of the Spring Data umbrella project), using bothXML and Java based configuration. The various method of defining more advancedcustom queriesare discussed, as well as configuration with the new jpanamespaceand transactional semantics. The final result is a new and elegant take ondata access with Spring, with almost no actual implementation work.

    You can check out the full implementation in the github project.

    https://github.com/eugenp/REST#readme
  • 8/10/2019 Persistence With Spring eBook

    31/45

    31

    The DAO with Spring 3 and Hibernate

    1. Overview

    This section will show how to implement the DAO with Spring and Hibernate. Forthe core Hibernate configuration, see the sections about >> Hibernate 3 and >>Hibernate 4 with Spring.

    2. No More Spring Templates

    Starting Spring 3.0 and Hibernate 3.0.1, the Spring HibernateTemplateis nolonger necessaryto manage the Hibernate Session. It is now possible to make use ofcontextual sessions sessions managed directly by Hibernateand activethroughout the scope of a transaction.

    As a consequence, it is now best practice to use the Hibernate API directly instead ofthe HibernateTemplate, which will effectively decouple the DAO layer implementationfrom Spring entirely.

    2.1. Exception Translation without the HibernateTemplate aliveand well

    Exception Translation was one of the responsibilities of HibernateTemplate translatingthe low level Hibernate exceptions to higher level, generic Spring exceptions.

    Without the template, this mechanism is still enabled and activefor all the DAOsannotated with the @Repositoryannotation. Under the hood, this uses a Spring beanpostprocessor that will advice all @Repositorybeans with all thePersistenceExceptionTranslatorfound in the Spring context.

    One thing to remember is that exception translation is done through proxies; in orderfor Spring to be able to create proxies around the DAO classes, these must not bedeclared final.

    http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/architecture.html#architecture-current-session
  • 8/10/2019 Persistence With Spring eBook

    32/45

    32

    2.2. Hibernate Session management without the Template

    When Hibernate support for contextual sessions came out, the HibernateTemplateessentially became obsolete; in fact, the javadoc of the class has been updated withthis advice (bold from the original):

    NOTE: As of Hibernate 3.0.1, transactional Hibernate access code can also be codedin plain Hibernate style. Hence, for newly started projects, consider adopting thestandard Hibernate3 style of coding data access objects instead, based on {@linkorg.hibernate.SessionFactory#getCurrentSession()}.

    3. The DAO

    Well start with the base DAO -an abstract, parametrized DAOwhich supports the

    common generic operations and is meant to be extended for each entity:

    public abstract classAbstractHibernateDAO< T extendsSerializable >{

    privateClass< T > clazz;

    @Autowired

    privateSessionFactory sessionFactory;

    public voidsetClazz( finalClass< T > clazzToSet ){

    clazz = clazzToSet;

    }

    publicT findOne( final long id ){ return (T) getCurrentSession().get( clazz, id );

    }

    public List< T > findAll(){

    returngetCurrentSession()

    .createQuery( "from " + clazz.getName() ).list();

    }

    public voidsave( finalT enty ){

    getCurrentSession().persist( enty );

    }

    publicT update( finalT enty ){

    return(T) getCurrentSession().merge( enty );

    }

    public voiddelete( finalT enty ){

    getCurrentSession().delete( enty );

    }

  • 8/10/2019 Persistence With Spring eBook

    33/45

    33

    public voiddeleteById( final longid ){

    finalT enty = findOne( id);

    delete( enty );

    }

    protected final Session getCurrentSession(){

    returnsessionFactory.getCurrentSession();

    }

    }

    A few aspects are interesting here as discussed, the abstract DAO does not extendany Spring template (such as HibernateTemplate). Instead, the HibernateSessionFactory is injected directly in the DAO, and will have the role of the mainHibernate API, through the contextual Sessionit exposes:

    this.sessionFactory.getCurrentSession();

    Also, note that the Classof the entity is passed in the constructor to be used in thegeneric operations.

    Now, lets look at an example implementation of this DAO, for a Fooentity:

    @Repository

    public classFooDAO extendsAbstractHibernateDAO< Foo >implementsIFooDAO{

    publicFooDAO(){

    setClazz(Foo.class );

    }

    }

    4. Conclusion

    This section covered the configuration and implementation of the persistence layer withHibernate and Spring 3.1, using both XML and Java based configuration.

    The reasons to stop relying on templates for the DAO layer was discussed, as well aspossible pitfalls of configuring Spring to manage transactions and the HibernateSession. The final result is a lightweight, clean DAO implementation, with almost nocompile-time reliance on Spring.

    The implementation of this simple project can be found in the github project this is anEclipse based project, so it should be easy to import and run as it is.

    https://github.com/eugenp/tutorials/tree/master/spring-hibernate4#readme
  • 8/10/2019 Persistence With Spring eBook

    34/45

    34

    The DAO with JPA and Spring

    1. Overview

    This section will show how to implement the DAO with Spring and JPA. For thecore JPA configuration, see >> the article about JPA with Spring.

    2. No More Spring Templates

    Starting with Spring 3.1, the JpaTemplateand the corresponding JpaDaoSupporthavebeendeprecated in favor of using the native Java Persistence API.

    Also, both of these classes are only relevant for JPA 1 (from the JpaTemplatejavadoc):

    Note that this class did not get upgraded to JPA 2.0 and never will.

    As a consequence, it is now best practice to use the Java Persistence API directlyinstead of the JpaTemplate.

    2.1. Exception Translation without the Template

    One of the responsibilities of JpaTemplatewas exception translation translatingthe low level exceptions into higher level, generic Spring exceptions.

    Without the template, exception translation is still enabled and fully functionalfor all DAOs annotated with @Repository. Spring implements this with a beanpostprocessor which will advice all @Repositorybeans with all thePersistenceExceptionTranslatorfound in the Container.

    It is also important to note that the exception translation mechanism usesproxies in order for Spring to be able to create proxies around the DAO classes,these must not be declared final.

    3. The DAO

  • 8/10/2019 Persistence With Spring eBook

    35/45

    35

    First, well implement the base layer for all the DAOs an abstract class using genericsand designed to be extended:

    public abstract classAbstractJpaDAO< T extendsSerializable > {

    private Class< T > clazz;

    @PersistenceContext

    EntyManager entyManager;

    public final voidsetClazz( Class< T > clazzToSet ){

    this.clazz = clazzToSet;

    }

    publicT findOne( longid ){

    return entyManager.find( clazz, id );

    }

    public List< T > findAll(){

    returnentyManager.createQuery( "from " + clazz.getName() )

    .getResultList();

    }

    public voidcreate( T enty ){

    entyManager.persist( enty );

    }

    publicT update( T enty ){

    returnentyManager.merge( enty );

    }

    public voiddelete( T enty ){

    entyManager.remove( enty );

    }

    public voiddeleteById( longentyId ){

    T enty = findOne( entyId );

    delete( enty );

    }

    }

    The main interesting aspect here is the way the EntityManageris injected usingthe standard @PersistenceContextannotation. Under the hood, this is handled by thePersistenceAnnotationBeanPostProcessor which processes the annotation, retrievesthe JPA entity manager from the contains and injects it.

    The persistence post processor is either created explicitly by defining it in theconfiguration, or automatically, by defining context:annotation-configorcontext:component-scanin the namespace config.

  • 8/10/2019 Persistence With Spring eBook

    36/45

    36

    Also, note that the entity Classis passed in the constructor to be used in the genericoperations:

    @Repository

    public classFooDAO extends AbstractJPADAO< Foo > implementsIFooDAO{

    publicFooDAO(){

    setClazz(Foo.class);

    }

    }

    4. Conclusion

    This sectionillustrated how to set up a DAO layer with Spring and JPA, using bothXML and Java based configuration. We also discussed why not to use the JpaTemplateand how to replace it with the EntityManager. The final result is a lightweight, clean

    DAO implementation, with almost no compile-time reliance on Spring.

    The implementation of this simple project can be found in the github project this is anEclipse based project, so it should be easy to import and run as it is.

    https://github.com/eugenp/tutorials/tree/master/spring-jpa#readmehttps://github.com/eugenp/tutorials/tree/master/spring-jpa#readme
  • 8/10/2019 Persistence With Spring eBook

    37/45

    37

    Simplify the DAO with Spring and JavaGenerics

    1. Overview

    This section will focus on simplifying the DAO layerby using a single, generifiedData Access Object for all entities in the system, which will result in elegant dataaccess, with no unnecessary clutter or verbosity.

    2. The Hibernate and JPA DAOs

    Most production codebases have some kind of DAO layer. Usually the implementationranges from multiple classes with no abstract base class to some kind of generifiedclass. However, one thing is consistent there is always more then one most likely,there is a one to one relation between the DAOs and the entities in the system.

    Also, depending on the level of generics involved, the actual implementations can varyfrom heavily duplicated code to almost empty, with the bulk of the logic grouped in abase abstract class.

    These multiple implementations can usually be replaced by a single parametrizedDAOused in such no functionality is lost by taking full advantage of the type safetyprovided by Java Generics.

    Two implementationsof this concept are presented next, one for a Hibernatecentric persistence layer and the other focusing on JPA. These implementation are byno means complete only some data access methods are included, but they can beeasily be made more thorough.

    2.1. The Abstract Hibernate DAO

    public abstract classAbstractHibernateDao< T extendsSerializable > {

    privateClass< T > clazz;

    @Autowired

  • 8/10/2019 Persistence With Spring eBook

    38/45

    38

    SessionFactory sessionFactory;

    public final voidsetClazz( Class< T > clazzToSet ){

    this.clazz = clazzToSet;

    }

    public T findOne(longid ){

    return(T) getCurrentSession().get( clazz, id );

    }

    publicList< T > findAll(){

    returngetCurrentSession().createQuery( "from " + clazz.getName() ).list();

    }

    public voidcreate( T enty ){

    getCurrentSession().persist( enty );

    }

    public voidupdate( T enty ){getCurrentSession().merge( enty );

    }

    public voiddelete( T enty ){

    getCurrentSession().delete( enty );

    }

    public voiddeleteById( longentyId ){

    T enty = findOne( entyId );

    delete( enty );

    }

    protected finalSession getCurrentSession(){

    returnsessionFactory.getCurrentSession();

    }

    }

    The DAO uses the Hibernate API directly, without relying on any Spring templates (such as HibernateTemplate). Using of templates, as well as management of theSessionFactorywhich is autowired in the DAO were covered in the>> Hibernate DAOsection.

    2.2. The Generic Hibernate DAO

    Now that the abstract DAO is done, we can implement it just once the generic DAOimplementation will become the only implementationneeded:

    @Repository

  • 8/10/2019 Persistence With Spring eBook

    39/45

    39

    @Scope( BeanDefinion.SCOPE_PROTOTYPE )

    public classGenericHibernateDao< T extendsSerializable >

    extendsAbstractHibernateDao< T >implementsIGenericDao< T >{

    //

    }

    First, note that the generic implementation is itself parametrized allowing the clientto choose the correct parameter in a case by case basis. This will mean that the clientsgets all the benefits of type safety without needing to create multiple artifacts for eachentity.

    Second, notice the prototype scopeof these generic DAO implementation. Using thisscope means that the Spring container will create a new instance of the DAO each timeit is requested (including on autowiring). That will allow a service to use multiple DAOswith different parameters for different entities, as needed.

    The reason this scope is so important is due to the way Spring initializes beans in thecontainer. Leaving the generic DAO without a scope would mean using the defaultsingleton scope, which would lead to a single instance of the DAO living in thecontainer. That would obviously be majorly restrictive for any kind of more complexscenario.

    The IGenericDaois simply an interface for all the DAO methods, so that we can injectour implementation with Spring in (or in whatever is needed):

    public interfaceIGenericDao {

    T findOne(final longid);

    List findAll();

    void create(final T enty);

    T update(final T enty);

    voiddelete(finalT enty);

    voiddeleteById(final longentyId);

    }

    2.3. The Abstract JPA DAO

    public abstract classAbstractJpaDao< TextendsSerializable > {

    privateClass< T > clazz;

  • 8/10/2019 Persistence With Spring eBook

    40/45

    40

    @PersistenceContext

    EntyManager entyManager;

    public voidsetClazz( Class< T > clazzToSet ){

    this.clazz = clazzToSet;

    }

    publicT findOne( Long id ){

    returnentyManager.find( clazz, id );

    }

    public List< T > findAll(){

    returnentyManager.createQuery( "from " + clazz.getName() )

    .getResultList();

    }

    public voidsave( T enty ){

    entyManager.persist( enty ); }

    public voidupdate( T enty ){

    entyManager.merge( enty );

    }

    public void delete( T enty ){

    entyManager.remove( enty );

    }

    public voiddeleteById( Long entyId ){

    T enty = getById( entyId ); delete( enty );

    }

    }

    Similar to the Hibernate DAO implementation, the Java Persistence API is used heredirectly, again not relying on the now deprecatedSpring JpaTemplate.

    2.4. The Generic JPA DAO

    Similar to the the Hibernate implementation, the JPA Data Access Object isstraighforward as well:

    @Repository

    @Scope( BeanDefinion.SCOPE_PROTOTYPE )

    public classGenericJpaDao< T extendsSerializable >

    extendsAbstractJpaDao< T > implementsIGenericDao< T >{

  • 8/10/2019 Persistence With Spring eBook

    41/45

    41

    //

    }

    3. Injecting this DAO

    There is now a single DAOto be injected by Spring; also, the Classneeds to bespecified:

    @Service

    class FooServiceimplementsIFooService{

    IGenericDao< Foo > dao;

    @Autowired

    public voidsetDao( IGenericDao< Foo > daoToSet ){

    dao = daoToSet;

    dao.setClazz( Foo.class );

    }

    // ...

    }

    Spring autowires the new DAO insteince using setter injectionso that theimplementation can be customized with the Classobject. After this point, the DAO isfully parametrized and ready to be used by the service.

    There are of course other ways that the class can be specified for the DAO viareflection, or even in XML. My preference is towards this simpler solution because of theimproved readability and transparency compared to using reflection.

    4. Conclusion

    This section discussed the simplification of the Data Access Layerby providing asingle, reusable implementation of a generic DAO. This implementation was presented

    in both a Hibernate and a JPA based environment. The result is a streamlinedpersistence layer, with no unnecessary clutter.

    For a step by step introduction about setting up the Spring context using Java basedconfiguration and the basic Maven pom for the project, see this article.

    http://www.baeldung.com/2011/10/20/bootstraping-a-web-application-with-spring-3-1-and-java-based-configuration-part-1/
  • 8/10/2019 Persistence With Spring eBook

    42/45

    42

    Transactions with Spring 3 and JPA

    1. Overview

    This sectionwill discuss the right way to configure Spring Transactions , how touse the @Transactionalannotation and common pitfalls.

    For a more in depth discussion on the core persistence configuration, check out the>>Spring with JPA section.

    There are two distinct ways to configure Transactions annotations and AOP eachwith their own advantages were going to discuss the more common annotationconfighere.

    2. Configure Transactions without XML

    Spring 3.1 introduces the @EnableTransactionManagementannotationto beused in on @Configurationclasses and enable transactional support:

    @Configuraon

    @EnableTransaconManagementpublic classPersistenceJPAConfig{

    @Bean

    public LocalContainerEntyManagerFactoryBean entyManagerFactoryBean(){

    ...

    }

    @Bean

    publicPlaormTransaconManager transaconManager(){

    JpaTransaconManager transaconManager = newJpaTransaconManager();

    transaconManager.setEntyManagerFactory(entyManagerFactoryBean().getObject() );

    return transaconManager;

    }

    }

    3. Configure Transactions with XML

  • 8/10/2019 Persistence With Spring eBook

    43/45

    43

    Before 3.1 or if Java is not an option, here is the XML configuration,using annotation-drivenand the namespace support:

    4. The @TransactionalAnnotation

    With transactions configured, a bean can now be annotated with @Transactional eitherat the class or method level:

    @Service

    @Transaconal

    public classFooService { ...

    }

    The annotation supports further configurationas well:

    the Propagation Typeof the transaction the Isolation Levelof the transaction a Timeoutfor the operation wrapped by the transaction a readOnlyflag a hint for the persistence provider that the transaction should

    be read only

    detailed Rollbackconfiguration

    5. Potential Pitfalls

    5.1. Transactions and Proxies

    At a high level, Spring creates proxies for all the classes annotated with@Transactional either on the class or on any of the methods. The proxy allows theframework to inject transactional logic before and after the method being invoked mainly for starting and committing the transaction.

    What is important to keep in mind is that, if the transactional bean is implementing aninterface, by default the proxy will be a Java Dynamic Proxy. This means that onlyexternal method calls that come in through the proxy will be intercepted any self-

  • 8/10/2019 Persistence With Spring eBook

    44/45

    44

    invocation calls will not start any transaction even if the method is annotatedwith @Transactional.

    Another caveat of using proxies is that only public methods should be annotatedwith @Transactional methods of any other visibilities will simply ignore the

    annotation silently as these are not proxied.

    This article discusses further proxying pitfalsin great detail here.

    5.2. Changing the Isolation level

    One of the major pitfalls when configuring Spring to work with JPA is that changing theisolation of the transaction semantics will not work JPA does not support customisolation levels. This is a limitation of JPA, not Spring; nevertheless changing the

    @Transactionalisolationproperty will result in:

    org.springframework.transaction.InvalidIsolationLevelException: Standard JPA doesnot support custom isolation levels use a special JpaDialect for your JPAimplementation

    5.3. Read Only Transactions

    The readOnlyflagusually generates confusion, especially when working with JPA;

    from the javadoc:

    This just serves as a hint for the actual transaction subsystem; it will not necessarilycause failure of write access attempts. A transaction manager which cannot interpretthe read-only hint will notthrow an exception when asked for a read-only transaction.

    The fact is that it cannot be guaranteedthat an insert or update will not occur whenthe readOnlyflag is set its behavior is vendor dependentwhereas JPA is vendoragnostic.

    It is also important to understand that the readOnlyflag is only relevant inside a

    transaction; if an operation occurs outside of a transactional context, the flag issimply ignored. A simple example of that would calling a method annotated with:

    1 @Transaconal( propagaon = Propagaon.SUPPORTS,readOnly = true)

    from a non-transactional context a transaction will not be created and the readOnlyflag will be ignored.

    https://jira.springsource.org/browse/SPR-5012http://nurkiewicz.blogspot.ro/2011/10/spring-pitfalls-proxying.html
  • 8/10/2019 Persistence With Spring eBook

    45/45

    5.4. Transaction Logging

    Transactional related issues can also be better understood by fine-tuning logginginthe transactional packages; the relevant package in Spring is

    org.springframework.transaction, which should be configured with a logging level of

    TRACE.

    6. Conclusion

    We covered the basic configuration of transactional semantics using both java and XML,how to use @Transactionaland best practices of a Transactional Strategy. The Springsupport for transactional testingas well as some common JPA pitfallswere alsodiscussed.

    The implementation of this simple project can be found in the github project this is anEclipse based project, so it should be easy to import and run as it is.

    https://github.com/eugenp/tutorials/tree/master/spring-jpa#readme