Setting up Spring JPA support

A basic setup to use JPA with Spring

Step 1 – Enable standard bean post processor for annotations

In spring config xml file, add the following:

<context:annotation-config/>

Step 2 – Setup entity manager factory and JPA transaction manager beans

In spring config xml file, add the followings:

<bean class=“org.springframework.orm.jpa.JpaTransactionManager” id=“transactionManager”>

 <property name=“entityManagerFactory” ref=“entityManagerFactory”/>

 </bean>

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

  <bean class=“org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean” id=“entityManagerFactory”>

        <property name=“dataSource” ref=“dataSource”/>

 </bean>

Step 3 – add persistence.xml file to classpath:/META-INF folder

For example, to use Hibernate as provider for MySQL:

<?xml version=“1.0” encoding=“UTF-8” standalone=“no”?>

<persistence xmlns=http://java.sun.com/xml/ns/persistence&#8221; xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance&#8221; version=“2.0” xsi:schemaLocation=http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd&#8221;>

<persistence-unit name=“persistenceUnit” transaction-type=“RESOURCE_LOCAL”>

        <provider>org.hibernate.ejb.HibernatePersistence</provider>

        <properties>

            <property name=“hibernate.dialect” value=“org.hibernate.dialect.MySQL5InnoDBDialect”/>

            <!– value=”create” to build a new database on each run; value=”update” to modify an existing database; value=”create-drop” means the same as “create” but also drops tables when Hibernate closes; value=”validate” makes no changes to the database –>

            <!–  property name=”hibernate.hbm2ddl.auto” value=”validate”/ –>

            <property name=“hibernate.ejb.naming_strategy” value=“org.hibernate.cfg.ImprovedNamingStrategy”/>

            <property name=“hibernate.connection.charSet” value=“UTF-8”/>

            <property name=“hibernate.show_sql” value=“true”/>

            <!– Uncomment the following two properties for JBoss only –>

            <!– property name=”hibernate.validator.apply_to_ddl” value=”false” /–>

            <!– property name=”hibernate.validator.autoregister_listeners” value=”false” /–>

        </properties>

    </persistence-unit>

</persistence>

Conclusion

That’s it. Now you should be able to have the entity manager injected by using annotation @PersistenceContext. For example:

@Repository
public class MyJPARepository {

@PersistenceContext
private EntityManager entityManager;

More information from Spring documentation here

Getting JSON from Spring 3 Controller

Spring 3 controller can generate JSON response transparently. All you need to do is to have jackson jar files in the web app classpath.  For example, a controller will look like:

@RequestMapping(value=”/example/get.action”, method=RequestMethod.GET)
public @ResponseBody Pizza getPizza() {
Pizza pizza = … // create object here
return pizza;
}

To get pizza object in JSON, the request header should have attribute Accept with value application/json.  Then json text will be returned by the controller in the response content, for example:

{

“base”:{“name”:”thin crust”},

“toppings”:[“bacon”,”olive”,”mushroom”],

“name”:”supreme”

}

Integration testing for Spring 3 Controllers

Introduction

A quick follow up post on writing integration tests for Spring 3 MVC controllers. For each controller class, we need to test:

  1. The request mapping annotations to ensure requests are wired properly to the intended methods.
  2. The request handling methods themselves.

This post will focus on how to test the request mappings.

Details

The codes I use here is largely from this blog post. I have to make a couple of minor changes to get it running in my development environment (Spring 3.0.3). In particular, I have to explicitly get beans using AnnotationMethodHandlerAdapter and DefaultAnnotationHandlerMapping classes to avoid the following exception:

NoSuchBeanDefinitionException … expected single bean but found 2

Hence my codes are like the followings with the original line commented out:

 /* this.handlerAdapter = applicationContext.getBean(HandlerAdapter.class);

*/

this.handlerAdapter = applicationContext.getBean(AnnotationMethodHandlerAdapter.class);

and

/* final HandlerMapping handlerMapping = applicationContext.getBean(HandlerMapping.class);

*/

final HandlerMapping handlerMapping = applicationContext.getBean(DefaultAnnotationHandlerMapping.class);

Examples

To test the following controller method for create a new tag resource:

@RequestMapping(value=”/tag/add.action”, method=RequestMethod.PUT)
public String put(@Valid @ModelAttribute(“tag”) TagDTO tagDTO, BindingResult result, Model model) {
if (result.hasErrors()) {
model.addAttribute(“errors”, result.toString());
return “admin/tag/error”;
}
// …
return “redirect:/admin/tags/list.action”;
}

I have to following 2 tests:

@Test
public void testCreateFail() throws Exception {
request.setMethod(“PUT”);
request.setRequestURI(“/admin/tag/add.action”);
final ModelAndView mav = handle(request, response);
assertNotNull(mav);
assertEquals(“admin/tag/error”, mav.getViewName());
}

@Test
public void testCreateOK() throws Exception {
request.setMethod(“PUT”);
request.setRequestURI(“/admin/tag/add.action”);
request.addParameter(“name”, “tag name”);
final ModelAndView mav = handle(request, response);
assertNotNull(mav);
assertEquals(“redirect:/admin/tags/list.action”, mav.getViewName());
}

The above should be rather self explanatory. Note that the HiddenHttpMethodFilter filter defined in the web.xml file to handle PUT/DELETE for RESTful requests is not invoked here and the PUT/DELETE methods have to be specified in the request’s setMethod() method explicitly as in the above examples.

Using @initBinder in Spring 3 Controller

This post shows a simple example of using @initBinder annotation in Spring 3 controller.

Consider the following domain model and controller for processing a order form submission:

domain model

public class Pizza {

@NotNull

private int quantity;

@NotNull

private PizzaBase base;

}

and

public class PizzaBase {

@NotNull

private long id;

}

controller

@Controller

public class BindExampleController {

@RequestMapping(value=”/example/submit.action”, method=RequestMethod.POST)

public String submitForm(@Valid @ModelAttribute(“pizza”) Pizza pizza) {

// method implementation here

}

}

In this example, an order form will use a drop down menu and send the id of the pizza base chosen. The controller therefore has to convert the base id into the corrresponding PizzaBase object. To do this, we need to:

(1) Create a custom property editor to handle pizza base id to PizzaBase object conversion. This can be easily done by subclassing PropertyEditorSupport:

public class PizzaBasePropertyEditor extends PropertyEditorSupport {

@Override

public void setAsText(String text) {

PizzaBase base = new PizzaBase();

base.setId(Long.parseLong(text));

setValue(base);

}

}

(2) Register above property editor to the controller using @initBinder annotation:

@InitBinder

public void initBinderAll(WebDataBinder binder) {

binder.registerCustomEditor(PizzaBase.class,  new PizzaBasePropertyEditor());

}

That’s it. The controller now expects a request parameter “base” corresponding to the id of the pizza base chosen. The custom property editor creates a PizzaBase object with same id and associates the object with the model attribute Pizza in the controller’s  submitForm() method before it is called.

Note that @initBinder has an optional attribute where you can specify the particular attribute(s) to apply the method. By default, it applies to all model attributes.

Writing unit tests with JUnit 4 annotations

Introduction

Starting with version 4, it is no longer necessary to extend class TestCase as in JUnit 3 (and before) to implement unit tests. Instead, you can use annotation to mark your POJO as a test class.

The basics

As an example, let say we want to write unit tests for the following class:

public class IntegerAdder {

public long add(int a, int b) {

if (a < 0 || b < 0) {

throw new IllegalArgumentException();

}

return a + b;

}

}

Now, we can create the POJO test class IntegerAdderTest:

public class IntegerAdderTest {

}

To initialize and clean up resources used by the class use the following annotations:

  • @Before – called to initialize before each test, equivalent to setUp() method.
  • @After – called to clean up after each test, equivalent to tearDown() method.
  • @BeforeClass – called once to initialize static resources before running all tests.
  • @AfterClass – called once to clean up after running all tests.

For example:

@Before

public void setUp() {

adder = new IntegerAdder();

System.out.println(“setup()”);

}

@After

public void tearDown() {

System.out.println(“tearDown()”);

}

@BeforeClass

public static void setUpClass() {

System.out.println(“setupClass()”);

}

@AfterClass

public static void tearDownClass() {

System.out.println(“tearDownClass()”);

}

To add an unit test, just write the test method and annotate it with @Test, for example:

@Test

public void testAddSucceed() {

System.out.println(“testAddSucceed()”);

assertEquals(0L, adder.add(0,0));

assertEquals(3L, adder.add(1,2));

}

@Test also comes with an “expected” attribute where you can use to write test case where an exception is expected. For example, the add() method in the IntegerAdder class would throw an IllegalArgumentException if any of its input arguments have negative values. The test method will hence be like this:

@Test(expected = IllegalArgumentException.class)

public void testAddFailed() {

System.out.println(“testAddFailed()”);

adder.add(0, -1); // should throw an exception

}

Putting it all together, the following output will be generated:

>setupClass()

>setup()

>testAddSucceed()

>tearDown()

>setup()

>testAddFailed()

>tearDown()

>tearDownClass()

Parameterized tests

In many cases, we would like to test a method with different arguments, e.g. to check that it is working for some boundary conditions. Instead of adding the method calls explicitly like in the testAddSucceed() method above, JUnit 4 allows you to setup a test class to run with multiple parameters. To do that:

  • Annotate test class with@RunWith tag

@RunWith (value = Parameterized.class)

public class IntegerAdderTest {…

  • Add class member to store data and create constructor with same number of arguments:

// Parameters

private int a;

private int b;

private long expectedSum;

public IntegerAdderTest(int a, int b, long sum) {

this.a = a;

this.b = b;

this.expectedSum = sum;

}

  • Add a static method to populate the parameters:

@Parameters

public static Collection<Object[]> data() {

Object[][] values = new Object[][] {

{0, 0, 0L},

{1, 2, 3L}

};

return Arrays.asList(values);

}

  • Write unit test methods using the parameters, for example:

@Test

public void testAddParameterized() {

System.out.println(“testAddParameterized (a, b, sum): ” + a + ” ” + b + ” ” + expectedSum);

assertEquals(expectedSum, adder.add(a, b));

}

The following output will be displayed when the test is run:

>setupClass()

>setup()

>testAddParameterized (a, b, sum): 0 0 0

>tearDown()

>setup()

>testAddParameterized (a, b, sum): 1 2 3

>tearDown()

>tearDownClass()

I have removed the test methods testAddSucced() and testAddFailed() above or they will be run multiple (2) times here. Note you can use @Ignore annotation on a test method to prevent it from running as well.

Using Spring 3 to implement RESTful webservice

Introduction

In this post, I will illustrate how to use Spring framework v.3 to implement RESTful webservices for create, read, update and delete (CRUD) operations.

Relationship between CRUD and HTTP Verbs

The mapping between CRUD and HTTP methods is summarized as below:

  • Create – PUT
  • Read – GET
  • Update – POST
  • Delete – DELETE

Note that browser form element only supports GET and POST. To handle PUT and DELETE, the form will need to send a hidden parameter with name “_method” to the server. For example, to submit a PUT request require following html:

<form action=”put.action” method=”post”>

<input type=”hidden” name=”_method” value=”put”/>

// …

<input type=”submit” value=”Add”/>

</form>

Or you can use the form tag in Spring.

Also, the HiddenHttpMethodFilter filter needs to be setup in the web.xml file:

<filter>
<filter-name>httpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>httpMethodFilter</filter-name>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
</filter-mapping>

Note that you will need to get ordering of filters right if you are handling multi-part requests. See the API documentation for more details.

CRUD Operations

As an example, I am going to show the request mappings for implementing the REST web services for CRUD operations on a tag resource in a Spring 3 Controller class.

Create maps to a PUT request in the format http://<mydomain>/tag/add.action

@RequestMapping(value=”/tag/add.action”, method=RequestMethod.PUT)

public String put(@Valid @ModelAttribute(“tag”) TagDTO tagDTO, BindingResult result, Model model) {
// …
}

Read maps to a GET request in the format http://<mydomain>/tag/1/view.action

@RequestMapping(value=”/tag/{id}/view.action”, method=RequestMethod.GET)
public String view(@PathVariable(“id”) Long id, Model model) {

// …

}

Update maps to a post request in the format http://<mydomain>/tag/update.action:

@RequestMapping(value=”/tag/update.action”, method=RequestMethod.POST)
public String update(@Valid @ModelAttribute(“tag”) TagDTO tagDTO, BindingResult result, Model model) {
// …
}

Delete maps to a delete request in the format http://<mydomain>/tag/delete.action

@RequestMapping(value=”/tag/delete.action”, method=RequestMethod.DELETE)

public String delete(@RequestParam(“id”) Long id) {

// …

}

That’s it for now.