This is a very simple Spring ORM example that shows you how to configure an application with Spring that uses

  • Dependency Injection (@Autowired annotation),
  • JPA EntityManager (provided by Hibernate),
  • Transactional methods (AOP configured).

Spring ORM Example with AOP Transactions

To configure the transactional methods we do not use @Transactional annotations now because we use aspect oriented approach now (eg.: we can say all methods in the service package starting with “get” is a read-only transactional method). We use in-memory database for this example to simplify, so no need for any database setup. This is a standalone application example.

(For @Transactional annotated approach please check this tutorial:
https://www.journaldev.com/7655/spring-orm-example-jpa-hibernate-transaction)

The project structure:

Spring ORM Example with AOP Transactions

We go through these files one by one and explain them:

1. Maven dependencies

We will first look into our pom.xml file for all the required dependencies and their versions. We have used Spring 4, and Hibernate 4 in this example.

  • We need spring-context and spring-orm as Spring dependencies.
  • spring-aop also comes with spring-context as it’s dependent library, so no need to add it.
  • aspectjweaver is spring-aop’s dependency, but we have to add it since it is not defined explicitly for spring-aop.
  • We use hibernate-entitymanager for using Hibernate as a JPA Vendor. hibernate-entitymanager is dependent to hibernate-core this why we don’t have to put hibernate-core in pom.xml explicitly.
  • We need also a JDBC driver as a dependency for DB access that Hibernate uses. In this example we used hsqldb that contains the JDBC driver, and a working in memory db also for this example. (If you want to use external database, you have to change this to that db’s JDBC driver, fe: PostgreSQL, or mysql-connector-java maven dependency.)

2. Model Class

We can use standard JPA annotations for mapping in our model because Hibernate provides JPA implementation.

We use @Entity and @Id JPA annotations to qualify our POJO as an Entity and defining it’s primary key.

3. Dao Class

We create a very simple DAO class, that have persist and findALL methods.

  • @Component is Spring annotation that tell the Spring container that we can use this class through Spring IoC (Dependency Injection).
  • We use JPA’s @PersistenceContext annotation that indicate dependency injection to an EntityManager. Spring injects a proper instance of EntityManager according to the spring.xml configuration.

4. Service Class

Our simple service class has 2 write and 1 read methods: add, addAll, and listAll.

Please note that

  • there are no @Transactional annotations before the methods, but we want these methods to be transactional. The reason is that we use AOP approach to configure which methods are transactional that will be configured in spring.xml below.
  • We use Spring’s @Autowired annotation to have ProductDao component be dependency injected.

5. Spring configuration XML

Now we have ready with every working classes needed in our mini application. Let’s create Spring’s configuration file:

  • First we tell spring that we want to use classpath scanning for Spring components (Services, DAOs, etc…) rather than unconviniently defining them one by one in this xml, and also we enable Spring annotation detection.
  • Adding the datasource, that is currently hsqldb (in-memory database).
  • We set up a JPA EntityManagerFactory that will used by the application to obtain an EntityManager. Spring supports 3 different ways to do this (see the reference below for details), and we use LocalContainerEntityManagerFactoryBean for full JPA capabilities.
    We set it’s attributes as:
  • packagesToScan attribute that points to our models’ package. (no need for persistence.xml)
  • datasource (defined above)
  • jpaVendorAdapter as Hibernate (also setting some hibernate property)
  • We configure the Spring-AOP behavior the following way: We want all methods in the service package transactional, and for methods starting with “get*” or “list*”, we want them to be read-only transactional. This simple.
  • We create Spring’s PlatformTransactionManager instance as a JpaTransactionManager. (This transaction manager is appropriate for applications that use a single JPA EntityManagerFactory for transactional data access.)

6. Spring ORM Example Test Class

Our setup is ready, so let’s write a testing class for our application.

You can see how simple we can start the Spring container from a main method, and getting our first dependency injected entry point, the service class instance. ProductDao class reference injected to the ProductService class after the context initialized.

After we got ProducService instance, we can test it’s methods, all method call will be transactioned due to Spring’s proxy mechanism. We also test rollback in this example.

If you run, you get below log:

Note that the second transaction rolled back, this why product list didn’t changed.

You can see that we made transactional methods without specifying them one by one with @Transactional annotations, as we configured it in AOP approach.

If you use log4j.properties file from attached source, you can see what’s going on under the hood.

References:
Object Relational Mapping (ORM) Data Access
Aspect Oriented Programming with Spring

(For @Transactional annotated approach please check this tutorial:
https://www.journaldev.com/7655/spring-orm-example-jpa-hibernate-transaction)

You can download the final maven project source from below link and play around with it to learn more.

By admin

Leave a Reply

%d bloggers like this: