Introduction
Required Software
- JDK 1.7
- Maven 2.2.x
- Eclipse for J2EE
Steps to write code
- Create a simple java project with src/main/java, src/main/resources as the source directory. Once project is created, you can add source directory from the below screen (Right click on project -> properties)
- Convert the project into maven project (Right click on the project -> Configure -> Convert to Maven project)
- Add the following dependancies in your pom.xml for Hibernate One to Many example
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>SpringAOP-TransactionManagement</groupId>
<artifactId>SpringAOP-TransactionManagement</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<spring.version>4.0.1.RELEASE</spring.version>
<aspectj.version>1.7.4</aspectj.version>
<hibernate.version>4.0.1.Final</hibernate.version>
</properties>
<repositories>
<repository>
<id>jboss</id>
<url>http://repository.jboss.org/maven2</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- This dependancy is required for spring ApplicationContext container -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring AOP dependency -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- AspectJ dependencies -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<!-- Spring datasource -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Hibernate Dependencies -->
<!-- Hibernate core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- Hibernate annotation -->
<dependency>
<groupId>hibernate-annotations</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.3.0.GA</version>
</dependency>
<dependency>
<groupId>hibernate-commons-annotations</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>3.0.0.GA</version>
</dependency>
<!-- Hibernate library dependecy start -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>
<!-- Hibernate library dependecy end -->
<!-- HSQL database -->
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.10</version>
</dependency>
</dependencies>
</project>
- Create other files as shown below
The purpose of each files are described in the below table
SL NO | Class Name | Description |
---|---|---|
1 | spring-config.xml | Data source, session factory and transaction management is configured in this file. In this file we can configure the methods for which the transaction management will be applied. Spring AOP and Dependency Injection configuration is done in this file |
2 | com.ashish.entity.EmployeeEntity and com.ashish.entity.EmployeeAllocationEntity | These two hibernate entity classes are having one to many relationsship. In EmployeeEntity class @OneToMany and in EmployeeAllocationEntity class @ManyToOne annotations are used to established the relationship in hibernate |
3 | com.ashish.dao.EmployeeDAO and com.ashish.dao.EmployeeDAOImpl | EmployeeDAOImpl implements insertRecords() and listRecords() methods of EmployeeDAO interface. |
4 | com.ashish.service.EmployeeService and com.ashish.service.EmployeeServiceImpl | EmployeeServiceImpl implements insertRecords() and listRecords() methods of EmployeeService interface. The Spring framework controlled transaction management is configured for insertRecords() method. If database the transaction fails it will get rolled back automatically. |
5 | com.ashish.aop.LoggingAspect | Audit Logging is done in this file. @Before and @AfterThrowing advises are implemented in this file. |
6 | com.ashish.main.MainApp | This class contains the main method and calls Employee services to insert records. |
- spring-config.xml
<?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:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="com.ashish" />
<!-- AspectJ: Audit Logging Aspect -->
<aop:aspectj-autoproxy />
<bean id="loggingAspect" class="com.ashish.aop.LoggingAspect"></bean>
<!-- Data source: DB connection properties -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:ashish" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<!-- Session Factory for the integration with Hibernate ORM -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.archive.autodetection">class</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.ashish.entity.EmployeeEntity</value>
<value>com.ashish.entity.EmployeeAllocationEntity</value>
</list>
</property>
</bean>
<!-- TransactionManager and TransactionInterceptor is used for the Spring
AOP Transaction Management -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="dataSource" ref="dataSource" />
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- We can manage transaction in two ways
1. By adding @Transactional(readOnly = false) on top of a method OR
2. By regex matching method name in the tx:advice as shown below
-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" read-only="true" />
<tx:method name="insert*" propagation="REQUIRED" read-only="false" />
</tx:attributes>
</tx:advice>
<!-- Below configuration says where we want to apply apply the transaction. In the below example we want to apply the transaction in
<aop:advisor advice-ref="txAdvice" pointcut-ref="createOperation" />
-->
<aop:config>
<aop:pointcut id="createOperation" expression="execution(* com.ashish.service.EmployeeService.insert*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="createOperation" />
</aop:config>
<bean id="employeeDao" class="com.ashish.dao.EmployeeDAOImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="employeeService" class="com.ashish.service.EmployeeServiceImpl">
<property name="employeeDao" ref="employeeDao"></property>
</bean>
</beans>
- EmployeeEntity.java: This class has a set to hold the one to many relationship.
- EmployeeAllocationEntity.java: @ManyToOne annotation is used to to establish the relationship.
@Entity
@org.hibernate.annotations.Entity(dynamicUpdate = true)
@Table(name = "EMPLOYEE_ALLOCATION", uniqueConstraints = {
@UniqueConstraint(columnNames = "ID") })
public class EmployeeAllocationEntity implements Serializable {
private static final long serialVersionUID = -1798070786993154676L;
@Id
@Column(name = "ID", unique = true, nullable = false)
private Integer allocationId;
@Column(name = "ALLOCATION_NAME", unique = true, nullable = false, length = 100)
private String allocationName;
@ManyToOne
@JoinColumn(name="employeeId")
private EmployeeEntity empEntity;
public EmployeeAllocationEntity(int allocationId, String allocationName, EmployeeEntity emp) {
this.allocationId = allocationId;
this.allocationName = allocationName;
this.empEntity = emp;
}
// All getter and setter methods
}
- EmployeeDAOImpl.java: EmployeeDAOImpl implements insertRecords() and listRecords() methods of EmployeeDAO interface
- EmployeeServiceImpl.java: Transaction management is done in the insertRecords() method. Transaction management can be done by @Transactional(readOnly = false) annotation or can be configured in the spring-config.xml file. In our example, we have done the configuration in the spring-config.xml file.
- LoggingAspect.java: Audit Logging is done in this file. @Before and @AfterThrowing advises are implemented in this file
package com.ashish.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class LoggingAspect {
@Before("execution(* com.ashish.service.EmployeeService.insert*(..))")
public void beforeExecution(JoinPoint jp) {
System.out.println("Before method: " + jp.getSignature().getName()
+ ". Class: " + jp.getTarget().getClass().getSimpleName());
}
@AfterThrowing(pointcut = "execution(* com.ashish.service.EmployeeService.insert*(..))", throwing = "ex")
public void afterThrowingExecution(JoinPoint jp, Exception ex) {
System.out.println("After throwing advice: "
+ jp.getSignature().getName() + ". Class: "
+ jp.getTarget().getClass().getSimpleName());
System.out.println("Exception: " + ex.getMessage());
}
}
- MainApp.java: This class contains the main method and calls DAO services.