Archive

Posts Tagged ‘Spring’

Spring + JTA + JPA + JMS

April 8th, 2010

I recently worked on a Spring application that used Hibernate as JPA provider and JTA for transaction demarcation. In this post I will create a simple Order Processing Message Driven Bean that showcases this integration. I will be using an Oracle database and deploy the application on a WebLogic 10.3 server.

To keep things manageable, the Message Driven Bean is designed to consume messages from a Queue. When a new message gets added to the Queue, the Application Server delivers it to the MDB. The MDB then uses a Spring Managed Service/Repository to persist a new “Order” JPA Entity in the database. The application is configured such that this entire process runs in a container managed transaction. I will be using the Blog Queue I created in a previous post.

Step 1: The first step is to create an Order Entity and the corresponding database table to store the newly created orders.

package com.inflinx.blog.orderprocessing.domain;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="ORDER_TABLE", schema="BLOGDEMO")
public class Order
{
	@Id
	@Column(name="ORDER_ID")
	private Long id;

	@Column(name="NAME")
	private String name;

	@Column(name="CREATED_DATE")
	private Date createdDate;

	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Date getCreatedDate() {
		return createdDate;
	}
	public void setCreatedDate(Date createdDate) {
		this.createdDate = createdDate;
	}
}

I have created the ORDER_TABLE in an Oracle database under the BLOGDEMO schema:

Order Table

Order Table

Step 2: In the WebLogic console, create a XA datasource to the database with the JNDI name jdbc.blgods.

XA Blog Data Source

XA Blog Data Source

The XA datasource is necessary for Hibernate to participate in a JTA global transaction. WebLogic also provides an option to emulate XA with the Emulate Two-Phase Commit.

Step 3: The next step is to create an OrderRepository that deals with persistence logic such as creating a new Order.

package com.inflinx.blog.orderprocessing.repository;

import com.inflinx.blog.orderprocessing.domain.Order;

public interface OrderRepository
{
	public void createOrder(Order order);
}
package com.inflinx.blog.orderprocessing.repository;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Repository;

import com.inflinx.blog.orderprocessing.domain.Order;

@Repository("orderRepository")
public class OrderRepositoryImpl implements OrderRepository
{
	// Spring injected EntityManager
	@PersistenceContext
    private EntityManager entityManager;

	@Override
	public void createOrder(Order order)
	{
		 entityManager.persist(order);
	}
}

Step 4: Following the principles of layered architecture, the next step is to create an OrderService and its implementation.

package com.inflinx.blog.orderprocessing.service;

import com.inflinx.blog.orderprocessing.domain.Order;

public interface OrderService {
	public void createOrder(Order order);
}
package com.inflinx.blog.orderprocessing.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.inflinx.blog.orderprocessing.domain.Order;
import com.inflinx.blog.orderprocessing.repository.OrderRepository;

@Service("orderService")
@Transactional
public class OrderServiceImpl implements OrderService {

	@Autowired
	@Qualifier("orderRepository")
	private OrderRepository orderRepository;

	@Override
	public void createOrder(Order order) {
		// Simply delegate the call to repository layer
		orderRepository.createOrder(order);
	}
}

As you can see, the implementation is annotated with @Transactional to make the service call transactional.

Step 5: The next step is to create a persistence.xml file without any JPA provider information.




			com.inflinx.blog.orderprocessing.domain.Order
		

Step 6: The next step is to create a Spring configuration application-context.xml file to hold bean and transaction definition. In addition, the file also holds the JPA provider information.



	
    

    

    

	

	
    

    

    				


    				
    			

    				
    					hibernate.transaction.factory_class=org.hibernate.transaction.JTATransactionFactory
					hibernate.transaction.manager_lookup_class=org.hibernate.transaction.WeblogicTransactionManagerLookup
					hibernate.current_session_context_class=jta
					hibernate.transaction.flush_before_completion=true
					hibernate.connection.release_mode=auto
    				
    			
    			

 

Step 7: With the above configuration in place, the next step is to create a Message Driven Bean that processes incoming messages. The MDB is annotated to use container managed transactions:

package com.inflinx.blog.mdb;

import java.util.Date;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.interceptor.Interceptors;
import javax.jms.Message;
import javax.jms.MessageListener;

import org.apache.commons.lang.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor;

import com.inflinx.blog.orderprocessing.domain.Order;
import com.inflinx.blog.orderprocessing.service.OrderService;

@MessageDriven(
		mappedName = "jndi.blogQueue",
		name="orderProcessor",
		activationConfig = { @ActivationConfigProperty(
				propertyName = "destinationType", propertyValue = "javax.jms.Queue"
		)}
)
@Interceptors(SpringBeanAutowiringInterceptor.class)
@TransactionManagement(TransactionManagementType.CONTAINER)
public class OrderProcessor implements MessageListener
{
	@Autowired
	@Qualifier("orderService")
	private OrderService orderService;

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
	public void onMessage(Message message)
	{
    	// Create a new Order
    	Order order = new Order();
    	order.setId(System.currentTimeMillis());
    	order.setName(RandomStringUtils.randomAlphabetic(5));
    	order.setCreatedDate(new Date());

    	// Save the order
    	orderService.createOrder(order);
	}

}

Step 8: The SpringBeanAutowiringInterceptor by default looks for a beanRefContext.xml file to create a spring context. So the final step in the process is to create a beanRefContext.xml with a reference to the application-context.xml.




	
		

				application-context.xml
			
		
	


Now when a new message gets added to the Queue, the onMessage method will run inside a transaction and will create a new Order. Here is a new Order record in the database:

Order Table Populated

Order Table Populated

Balaji JMS, JPA, JTA, Spring , , ,

Spring Ehcache Integration

February 26th, 2009

In this post I will share how to cache method results using Ehcache and Spring AOP. This is based on the post

The first step is to add all the required jars to the project. At minimum, the following jars should be present:

Spring and related jars (using 2.5.6 version here):

  • spring-2.5.6.jar
  • commons-logging.jar
  • commons-collections.jar
  • aspectjrt.jar
  • aspectjweaver.jar
  • jsr250-api-1.0.jar

Ehcache and its dependencies (using version 1.5.0):

  • ehcache-1.5.0.jar
  • backport-util-concurrent-3.0.jar
  • jsr107cache-1.0.jar

For the sake of this post, I will be using a DemoService with a method whose results need to be cached.

package com.inflinx.blog.service;
import java.util.List;
public interface DemoService
{
	public List getCarTypes(String filter);
}

Here is a dummy implementation of the above service:

package com.inflinx.blog.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;

@Service("demoService")
public class DemoServiceImpl implements DemoService
{

	public List getCarTypes(String filter)
	{
		List carTypes = new ArrayList();
		carTypes.add("Mini");
		carTypes.add("Economy");
		carTypes.add("Sport Utility");
		carTypes.add("Convertible");
		carTypes.add("Standard");

		return carTypes;
	}
}

And the application context with bean scanning turned on:





       


The next step in the process is to add ehcache.xml to the classpath. Details on this configuration file can be found at Ehcache web site



	

	
	


Spring makes integration with Ehcache easy with EhCacheManagerFactoryBean and EhCacheFactoryBean classes. The EhCacheManagerFactoryBean provides access to Ehcache’s CacheManager and the EhCacheFactoryBean exposes caches defined in ehcache.xml.

To make use of these beans, lets add the following to the application context file:




The next step is to create an AOP Aspect that would provide caching transparently:

package com.inflinx.blog.aspect;

import javax.annotation.Resource;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component("cacheAspect")
@Aspect
@Order(2)
public class CacheAspect
{
	@Resource(name="carTypesCache")
	private Cache cache;

	@Around("execution(* com.inflinx.blog.service.DemoService.getCarTypes(java.lang.String))")
	public Object cacheCarTypes(ProceedingJoinPoint joinPoint) throws Throwable
	{
		Object[] arguments = joinPoint.getArgs();
		String location = (String)arguments[0];
		Element element = cache.get(location);
		if(null == element)
		{
			Object result = joinPoint.proceed();
			if(null != result)
			{
				element = new Element(location, result);
				cache.put(element);
			}
		}
		return element != null ? element.getValue() : null;
	}
}

Finally, declare the newly created aspect in the application context file:




Spring Modules provides a great alternative for declarative caching with @Cacheable annotation. As of this post, Spring Modules is still in “draft” status.

You can download the source code used in this post here

Balaji Spring ,

Integrating Quartz with Spring

September 24th, 2008

Spring’s reference documentation goes over in detail on integrating Quartz with Spring. However, the technique requires extending Spring’s QuartzJobBean class. Here are steps for achieving the same integration with out dependencies on QuartzJobBean class:

Step 1: Create the Quartz job that needs to be scheduled. Here is a simple Hello world job class:

public class HelloWorldJob implements Job
{
  public void execute(JobExecutionContext jobExecutionContextthrows JobExecutionException
  {
    System.out.println("Hello World");
  }
}
Notice that we are simply implementing org.quartz.Job interface.

Step 2: In the Spring’s context file, define a JobDetail bean for this job. A JobDetail contains metadata for the job such as the group a job would belong to etc.

<?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:p=”http://www.springframework.org/schema/p” xmlns:context=”http://www.springframework.org/schema/context
   xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd“>
 
 <bean id=”helloWorldJobDetail” class=”org.quartz.JobDetail”>
      <property name=”name” value=”helloWorldJobDetail” />
      <property name=”jobClass” value=”local.quartz.job.HelloWorldJob” />
 </bean>

Step 3: Again, in the context file, define a Trigger that would trigger the job execution. For simplicity sake, lets use a SimpleTrigger. More about triggers can be found in the Quartz documentation:

 <bean id=”simpleTrigger” class=”org.quartz.SimpleTrigger”>
     <property name=”name” value=”simpleTrigger” />
     <property name=”jobName” value=”helloWorldJobDetail” />
     <property name=”startTime”>
       <bean class=”java.util.Date” />   
     </property>
  </bean>

The startTime property is set to “now” which means that the job will run as soon as the spring completes bean loading.

Step 4: Finally, define a SchedulerFactoryBean that sets up the Quartz scheduler:

<bean class=”org.springframework.scheduling.quartz.SchedulerFactoryBean”>
     <property name=”jobDetails”>
        <list> <ref bean=”helloWorldJobDetail” /> </list>
     </property>
     <property name=”triggers”>
        <list> <ref bean=”simpleTrigger” /> </list>
     </property>
 </bean>

Notice that this is the only Spring class used in the configuration. When the application loads the Spring context, the job should run and print “Hello World”

In most cases, the job instances rely on external services to perform their job (such as an email service to send out email). These external components can be easily made available to the job instances via dependency injection. Let’s modify the above class to display a custom message:

 public class HelloWorldJob implements Job
{
  private String message;
  
  public void setMessage(String message)
  {
    this.message = message;
  }
  
  public void execute(JobExecutionContext jobExecutionContextthrows JobExecutionException
  {
    System.out.println(message);
  }
}

Next, in the Spring context file, add a bean that contains the custom message we want to display:

<bean id=”message” class=”java.lang.String”>
  <constructor-arg value=”Hello Again!!” />
 </bean>

With Quartz 1.5 and above, dependency Injection into Quartz jobs can be done via a JobFactory instance. Here are the modifications that need to be done to the Spring context:

<bean id=”jobFactory” class=”org.springframework.scheduling.quartz.SpringBeanJobFactory” />
 
 <bean class=”org.springframework.scheduling.quartz.SchedulerFactoryBean”>
      <property name=”jobFactory” ref=”jobFactory” />
      <property name=”schedulerContextAsMap”>
          <map> <entry key=”message” value-ref=”message” /> </map>   
      </property>
      <property name=”jobDetails”>
         <list> <ref bean=”helloWorldJobDetail” /> </list>
      </property>
      <property name=”triggers”>
        <list> <ref bean=”simpleTrigger” /> </list>
       </property>
  </bean>

Now when the Spring context gets loaded, the job should run and print “Hello Again!!”.

Balaji Quartz, Spring ,