Archive for July, 2008

Spring Transaction Management using Aspects

For the sake of doing dependency injection into some Hibernate loaded domain classes (see previous post), I was forced to change an application to use AspectJ for it’s aspect weaving. When I did this, it broke my existing usage of the Spring @Transaction annotation.

Here’s what I had to do to fix it.

1. Define my transaction as annotation driven in the application context file.

<tx:annotation-driven transaction-manager="transactionManager" mode="aspectj"/>

2. Manually set the transactionManager on the AnnotationTransactionAspect class. Supposedly, this is a bug in Spring pre 2.5.x, but I was still encountering it even in 2.5.5.

<bean class="org.springframework.transaction.aspectj.AnnotationTransactionAspect" factory-method="aspectOf" dependency-check="none">
<property name="transactionManager" ref="transactionManager"/>
</bean>

Comments

Domain Model Dependency Injection

I recently had the need to add some rich features to an existing domain model. The application is built with Spring 2.5.x and Hibernate. When I started on this endeavor, I had no idea how many issues I would encounter. So, here’s what I ultimately had to do to get DI in my Hibernate loaded domain classes.

1. Use the @Configurable annotation on your domain class that you want to do DI with.
2. Use the @Autowired annotation on the member variable that needs DI.

@Configurable
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="material_type", discriminatorType=DiscriminatorType.STRING)
@org.hibernate.annotations.ForceDiscriminator
@Table(
name = "materials",
uniqueConstraints = {@UniqueConstraint(columnNames={"material_id"})}
)
public abstract class MaterialContent {
@Autowired
@Transient
protected ProtectedFileUrlDao protectedFileUrlDao;
}

3. Define the Autowired member variable as a bean in your application context file (there’s of course other ways to do this).

<bean id="protectedFileURLDao" class="com.sample.impl.ProtectedFileURLDaoImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>

4. Setup the standard application context settings to allow for Annotation DI. By default, spring will use compile-time weaving (fine by me).

<context:component-scan base-package="com.sample"/>
<context:spring-configured/>
<context:annotation-config/>

5. Setup your maven pom to compile the code with the AspecJ weaver.

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.0</version>
<configuration>
<source>1.5</source>
<verbose>true</verbose>
<complianceLevel>1.5</complianceLevel>
<showWeaveInfo>true</showWeaveInfo>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>
</plugin>

Here’s some of the references that I used while setting this up:

Chris Richardson - enterprise POJOs
New Improvements in Domain Object Dependency Injection Feature

Comments