blog.smart-java.nl
Ordina J-Technologies – Java Blog

Archief voor January, 2010




JSF 2.0: The most simple CDI integration use cases

Door: Jan-Kees van Andel, 31 January 2010

If you have (just like me) been following the Web Beans and Contexts and Dependency Injection (CDI) work, you might be thinking (also just like I did): “That CDI is heavily over-engineered”. My “moment of clarity” was a year ago, at DeVoxx 2008.

It was a talk by Pete Muir of JBoss. He was showing a really simple use case and tried to implement it using CDI. The talk was really technology driven and I hated it. Why? Because it wasn’t an improvement compared with the existing technologies. He wrote an application, containing several interfaces, classes (this is not bad) and custom annotations. If the goal was to show some kind of geniosity, it was a good talk. But if the goal was to show how this new technology would make our lives better… then sorry, he failed miserably.

More than a year further, there have been a lot of movements on the CDI front. And, as an Apache MyFaces developer, I’m of course very interested how to use CDI in a JSF 2.0 application. And as an Apache fanboy, I of course prefer Apache software, in this case MyFaces with OpenWebBeans and OpenJPA.

Configuration
Since OpenWebBeans is still under development, you need to do some additional steps to get it to work.

The following POM should get you up and running quickly in Tomcat:

<?xml version="1.0" encoding="UTF-8"?>
<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>org.apache.myfaces</groupId>
    <artifactId>myfaces-example-ebanking</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
        <!-- Compile dependencies -->
        <dependency>
            <groupId>org.apache.myfaces.core</groupId>
            <artifactId>myfaces-api</artifactId>
            <version>${myfaces-version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.myfaces.core</groupId>
            <artifactId>myfaces-impl</artifactId>
            <version>${myfaces-version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.openjpa</groupId>
            <artifactId>openjpa-all</artifactId>
            <version>${openjpa-version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>commons-digester</groupId>
            <artifactId>commons-digester</artifactId>
            <version>2.0</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.openwebbeans</groupId>
            <artifactId>openwebbeans-impl</artifactId>
            <version>${openwebbeans.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.openwebbeans</groupId>
            <artifactId>openwebbeans-jsf</artifactId>
            <version>${openwebbeans.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.geronimo.specs</groupId>
            <artifactId>geronimo-interceptor_1.1_spec</artifactId>
            <version>1.0.0-EA1-SNAPSHOT</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>jsr250-api</artifactId>
            <version>1.0</version>
            <scope>compile</scope>
        </dependency>

        <!-- Test dependencies -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
            <version>${junit-version}</version>
        </dependency>
    </dependencies>

    <repositories>
        <repository>
            <id>Apache MyFaces beta</id>
            <name>Apache MyFaces beta</name>
            <url>http://people.apache.org/~lu4242/myfaces200beta</url>
        </repository>
    </repositories>

    <properties>
        <myfaces-version>2.0.0-beta</myfaces-version>
        <openwebbeans.version>1.0.0-SNAPSHOT</openwebbeans.version>
        <openjpa-version>2.0.0-M3</openjpa-version>
        <junit-version>4.7</junit-version>
    </properties>
</project>

Note some of the additional dependencies required to run in Tomcat, as opposed to a full blown appserver.

Also, at the moment you need to build OpenWebBeans from source manually. The geronimo-interceptor_1.1_spec dependency will be downloaded to your local Maven repository on a “mvn install”. OpenJPA is not needed for this simple use case, but I use it in my project.

Code
And then, the real code:

public class WebUtils {
    private static volatile String basePath;

    @Produces @Named public String getBasePath() {
        if (basePath == null) {
            basePath = FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath();
        }
        return basePath;
    }
}

This class contains a so-called Producer Method. As the name suggests, it produces stuff. In this case, it produces a String with Dependent scope. This means the method will be invoked every time the variable is needed. EL expressions or injection are the most common cases for this.

I’m caching the return value, though it’s not necessary, since getting the context path is pretty cheap.

The view could look like this (snippet):

...
<link href="#{basePath}/style/default.css" rel="stylesheet" type="text/css" />
...

Another implementation could put the variable into the Application scope, like this:

public class WebUtils {
    @Produces @Named @ApplicationScoped public String getBasePath() {
        return FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath();
    }
}

As easy it might seem, the approaches shown above require some responsibility from the programmer though. With producer methods, it becomes really easy to mess things up. After all, you’re effectively creating globals. Tool support may help you here though. For example, the Dependency Analyzer in IntelliJ IDEA 9.0.1 already contains pretty decent support for JSF 2.0 and CDI. And, knowing the reputation of the JetBrains folks, I’m sure they come up with even more fancy stuff.

A more classic implementation
A more classic implementation could look like the following:

@Named
@ApplicationScoped
public class WebBean {
    private static volatile String basePath;

    public String getBasePath() {
        if (basePath == null) {
            basePath = FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath();
        }
        return basePath;
    }
}

I’m not using producer methods anymore. The WebBean is now a CDI-managed bean.

The client code becomes slightly more verbose, but who cares? I’ll put the client code in a generic template anyway!:

...
<link href="#{webBean.basePath}/style/default.css" rel="stylesheet" type="text/css" />
...

Wrapping up
I haven’t even showed the complete tip of the iceberg. CDI offers several ways to write code and we’ve yet to find out the (anti) patterns.

I would like to point you to the OpenWebBeans documentation for more info, but unfortunately this is still under development. The good news is that JBoss Weld already has extensive documentation.




JSF 2.0: Maximum flexibility with System Events

Door: Jan-Kees van Andel, 24 January 2010

JSF 2.0 adds a lot of interesting features. Andy Schwartz provides an extensive overview on his blog.

On this blog, I’d like to elaborate a bit further on the interesting features JSF 2.0 has to offer.

JSF 2.0: System Events
JSF 2.0 comes with a useful feature, called System events. System events are predefined events that are published at predefined points in the lifecycle.
System events are either global or component system events.

Global system events
An example of a global system event is PostConstructApplicationEvent, which is published when all configuration is done. It can be seen as a JSF replacement for ServletContextListener.

Listener registration is done by invoking Application.subscribeToEvent(Class<? extends SystemEvent> type, SystemEventListener listener).

Component system events
Component system events only apply to the component to which the listener is attached.

An example of a component system event is PreRenderComponentEvent. This event is published to the appropriate component when it’s about to be rendered.

Listener registration is done by invoking UIComponent.subscribeToEvent(Class<? extends SystemEvent> type, ComponentSystemEventListener listener).

<f:event /> tag
The JSF 2.0 spec also defines the <f:event /> tag, which needs to be nested inside a component tag in the web page. This tag is used to make listener registration easier. Just nest the tag inside a component tag in your Facelet, specify the event to listen to and specify a MethodExpression to your listener method and everything works.

An example
Below is an example of an e-banking login page. It uses a challenge-response authentication mechanism, so it generates a “random” challenge when the page is loaded. Because users can navigate to the login page directly (GET-request), we can’t rely on an action method to be invoked first, so let’s fix this using system events.

First, a bit of history
I’ve always hated to write “the first” page in JSF. Since JSF short circuits the lifecycle in the case of a GET request, you don’t really have an appropriate hook for page initialization, making it difficult to create a dynamic landing page.

One could write “lazy getters”:

public class MyBackingBean {
    private List accounts;

    public List getAccounts() { // Yuck
        if (accounts == null) {
            // Do some expensive database query
            accounts = doSomeWork();
        }
        return accounts;
    }
}

It’s quite obvious this is extremely nasty. You don’t know when the getter is invoked (EL triggers the invocation), and that if-null check is also ugly. Btw. getters with logic are ugly anyway…

JSF 1.2 offered a slightly more elegant option with @PostConstruct:

public class MyBackingBean {
    private List accounts;

    @PostConstruct
    public void init() {
        accounts = doSomeWork();
    }

    public List getAccounts() { // Still not good
        return accounts;
    }
}

This is a bit better, but still not very good. The exact point of invocation within the lifecycle is still not obvious. But at least we now know the init() method won’t be invoked multiple times.

There are other ways to tackle this issue, for example, using a PhaseListener, or using a framework like Seam, but that has issues of its own.

Back to the event example
Below is a snippet of my login page.

<h:form>
  <dl>
    <dt><h:outputLabel value="Customer ID" for="customerId" /></dt>
    <dd><h:inputText id="customerId" value="#{loginBean.customerId}" required="true" /></dd>
    <dt><h:outputLabel value="Challenge" for="challenge" /></dt>
    <dd><h:outputText id="challenge" value="#{loginBean.challenge}">
      <f:event name="preRenderComponent" listener="#{loginBean.generateChallenge}" />
    </h:outputText></dd>
    <dt><h:outputLabel value="Response (always 123456)" for="response" /></dt>
    <dd><h:inputSecret id="response" value="#{loginBean.response}" required="true" /></dd>
    <dt> </dt>
    <dd><h:commandButton value="Login" action="#{loginBean.loginUsingTokenGenerator}" /></dd>
  </dl>
</h:form>

As you can see, the above snippet contains the challenge response login form. Line 7 is the interesting one. It registers a PreRenderComponentEvent listener method on the LoginBean.

The LoginBean is shown next (snippet…).

@Named
@SessionScoped
public class LoginBean implements Serializable {
    private Integer customerId;
    private Integer challenge;
    private Integer response;
    private @Inject LoginService loginService;
    private Customer customer;
    // Getters and setters

    public void generateChallenge(ComponentSystemEvent event) throws AbortProcessingException {
        this.challenge = loginService.generateChallenge();
    }

    public String loginUsingTokenGenerator() {
        customer = loginService.loginUsingTokenGenerator(customerId, challenge, response);
        if (customer == null) {
            FacesContext.getCurrentInstance().addMessage(null,
                        new FacesMessage(
                        "Username and/or password is incorrect or your account has been disabled"));
            return null;
        } else {
            return "/pages/homepage.xhtml?faces-redirect=true";
        }
    }
}

Don’t mind the annotations, they come from CDI (JSR-330 a.k.a. Contexts and Dependency Injection). The only thing to remember from these is that this class is a Session scoped managed bean which gets a LoginService injected. Note that I would also prefer ViewScoped, instead of SessionScoped.

Also, don’t mind the return values in loginUsingTokenGenerator. This is also a new feature in JSF 2.0, called Implicit Navigation.

Note the generateChallenge() method. The throws clause is not mandatory. The argument type must be ComponentSystemEvent though.

Wrapping up
As you can see, System events and the <f:event /> tag provide a convenient way to hook in custom logic on a per-component basis.

And, because we’re back to normal OO programming, instead of getter hacking, unit testing the LoginBean is easy as pie!

Pretty neat huh?! ;-)




java.util.Calendar.getActualMaximum returns strange results

Door: Peter Schuler, 20 January 2010

At the end of last year I encountered something odd in the java.util.Calendar. Now is odd behavior nothing to be surprised of in the Java Calendar but this particular oddness was really hard to spot.

I will therefore share it with you.

The code

Let’s first look a some code dealing with getting the last day of the month:

public class CalendarTest {
  public static void main(String[] args) {
    Calendar c = Calendar.getInstance();
    c.set(Calendar.MONTH, Calendar.FEBRUARY);
    int maxDayOfMonth = c.getActualMaximum(Calendar.DAY_OF_MONTH);

    System.out.println("last day of month = " + maxDayOfMonth);
  }
}

Please read the java doc for Calendar.getActualMaximum():

Returns the maximum value that the specified calendar field could have, given the time value of this Calendar. For example, the actual maximum value of the MONTH field is 12 in some years, and 13 in other years in the Hebrew calendar system.

So the code above can print two different values right …? 28 or 29 depending on the whether this year is a leap year. As you could have guessed that is another unexpected possibility. I can also print 31. Yes… really.

I all depends on the date on which this code is executed.

The problem is that Calendar.getInstance() will return a Calendar filled with the current date/time. Let’s assume the above code runs on the last day of January. The call to getInstance() will return 31-01-2009. The next step puts the month to February. This will result in a overflow as 31-02-2009 is invalid. Because of this Calendar will move the date to 3-03-2000. And March has 31 days.

There is a bug report (status: Closed, Not a Defect) in the SDN which told me that the observed behavior was correct. I was not the first person surprised by this and I’m guessing I will not be the last.

I was …

  1. … lucky I wrote a decent unit test.
  2. … lucky to be running said unit test om 31 December.
  3. … unlucky for having to work on the last day of the year.

Otherwise the bug I created would properly have slipped through the QA cycles and would have ended up in production. There it would only be visible on the last three days of every month if someone would specify a date in February.

What about lenient?
The Calendar.setLenient function does protect against invalid input. Let’s quote the the Calendar java doc about Leniency:

Leniency
Calendar has two modes for interpreting the calendar fields, lenient and non-lenient. When a Calendar is in lenient mode, it accepts a wider range of calendar field values than it produces. When a Calendar recomputes calendar field values for return by get(), all of the calendar fields are normalized. For example, a lenient GregorianCalendar interprets MONTH == JANUARY, DAY_OF_MONTH == 32 as February 1.

When a Calendar is in non-lenient mode, it throws an exception if there is any inconsistency in its calendar fields. For example, a GregorianCalendar always produces DAY_OF_MONTH values between 1 and the length of the month. A non-lenient GregorianCalendar throws an exception upon calculating its time or calendar field values if any out-of-range field value has been set.

So lenient does protect against the programmer/user creating a invalid date in a way that the following code will result in an exception:

    Calendar c = Calendar.getInstance();
    c.setLenient(false);
    c.set(Calendar.MONTH, Calendar.FEBRUARY);
    c.set(Calendar.DAY_OF_MONTH, 31);
    System.out.println(c.getTime());

But the exception is only thrown when c.getTime() is called. Calls to getActualMaximum() still work and return 31. So lenient is not useful here.

Lessons learned

The quick fix for this problem is to set the DAY_OF_MONTH to 1 (or any number between 1 and 28) before setting the month.

I also learned that Calendar.setLenient() will not protect you from this error. It will only stop you from getting an invalid Date. It does not protect against overflows.

Sould I use JODA time?

At the end of this post I have a question for you. I have no experience with JODA time always preferring to use the standard Date/Time API unless there was a problem. But perhaps I should reverse my views and use JODA time unless I’m not allowed too? What do you think … is it time to stop  using the default Calendar API and use JODA time instead? Or should I wait for Java 7 with JSR 310?




Spring 3.0: REST services with Spring MVC

Door: Stephan Oudmaijer, 16 January 2010

Spring 3.0 has support for REST style WebServices, the Spring MVC controllers facilitate the functionality. In this example I will show an example of how to implement a basic REST service that uses XML marshalling to sent information over HTTP. Disclamier: this is not an in depth tutorial for building REST style WebServices.

The Spring MVC controller

The Spring 3.0 REST support relies havily on Spring MVC. We should use the Controller class for implementing a REST style WeService. To declare a Controller I use the Spring annotation based configuration. In this example the ProductRestService class is annotated with @Controller annotation. In order for Spring to pick-up the annotation Spring needs to be configured to scan for annotation (see the Spring configuration section).

REST uses templates that describe the URI to be used to invoke a WebService method. These URI templates can contain variable placeholders which allow for passing information to the WebService. The URI should typically contain all the information required for invoking a WebService method.

The @RequestMapping annotation allowes you to define the URI and HTTP method that are mapped to a method. In this example I have annotated the ProductRestService.getProductById(Long productId) with the @RequestMapping.
The value of the @RequestMapping, in this case: /products/{productId} , defines the URI that is mapped to this method. The productId variable needs to be defined when invoking the method and will be resolved automatically by Spring MVC with the value from the request URI. You can use the @PathVariable to inject the value of the productId variable directly into a method parameter.

The @ResponseBody annotation tells Spring to marshall the return value of the method to the HTTP response body. Spring allowes you to configure HTTP message converters that take care of conversion of the return value to a format which is accepted by the client. In this example the return value will be marshalled to XML using XStream.

package com.oudmaijer.spring.rest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 *  This is an example REST style MVC controller. It serves as an
 *  endpoint for retrieving Product Objects.
 */
@Controller
public class ProductRestService {

    /**
     * This method returns a specific Product. The URI to request a Product is
     * specified in the @RequestMapping.
     *
     * @param productId the identifier of the requested product
     * @return a Product
     */
    @RequestMapping(value="/products/{productId}", method = RequestMethod.GET)
    @ResponseBody
    public Product getProductById(@PathVariable Long productId) {
        Product p = new Product();
        p.setId(productId);
        return p;
    }

}

Spring configuration

The configuration is where all the magic happens. It is important to define the <mvc:annotation-driven /> element at the end of the configuration file or else Spring will not register the marshallingHttpMessageConverter. It took me some time to figure this out ;(

You need to add the MessageConverters to the configuration in order to get the OXM marshalling to work. Spring uses the requests Accept header to determine which converter to use.


Maven2 dependencies

You need to add a couple of Maven2 dependencies to get the project up and running. Below is the entire pom.xml.

Web deployment descriptor: web.xml

Last but not least the web.xml. Since the REST support in Spring is based on Spring MVC you need to define the DispatcherServlet. Make sure to map the correct URL pattern to the DispatcherServlet.

Invoking the service

This example only supports the HTTP GET method. If you want to test or build a client that uses REST WebServices you should use the RestTemplate in Spring. We can easily validate if the example WebService is running by accessing the service through Firefox. This will result in the following response.

For more information on REST support in Spring 3.0 please refer to the Spring reference documentation.




Mockito

Door: Sander Abbink, 15 January 2010

If you want to test objects in isolation it is often usefull to use Mocks. Here is how you can do this with the Mockito framework.

First the maven dependency:

 org.mockito
  mockito-all
  1.8.1

If you don’t use a Maven plugin in let’s say Eclipse, then you can create a directory testlib which contains the jar. Add this jar to the buildpath (this won’t affect the Maven build).

It is also handy to use the following static imports:

   import static org.mockito.Mockito.*;
   import static org.junit.Assert.*;

Tip for Eclipse: if you want to prevent organize imports (ctrl+shift+o) to resolve the static imports: java -> code style -> organize imports -> Number of static imports needed for (set to 1).

Creating a Mock object:

   List mockedlist = mock(ArrayList.class);
   mockedlist.add("Hello");
   String value = mockedlist.get(0);
   mockedlist.get(5);

All the methods in ArrayList are mocked. So the String “Hello” won’t actually be added to the List (e.g. value == null). Also get(5) won’t throw an IndexOutOfBoundsException.

You can also stub method calls, like this:

   List mockedlist = mock(ArrayList.class);
   when(mockedlist.get(0)).thenReturn("Hello");

Or verify invocations:

   String value = "Hello";
   verify(mockedlist).get(0);
   verify(mockedlist).add(eq(value));
   verifyNoMoreInteractions(mockedlist);

eq is a method in the Matchers class. It will verify that an object is added to the mocked List which is equal to the String “Hello”. If you use a Matcher for one argument in a method, then you have to use a Matcher for all the other arguments too.

See javadoc for the other Matchers methods http://mockito.googlecode.com/svn/branches/1.5/javadoc/org/mockito/Matchers.html

You can also write your own Matcher, although this is rarely neccesary. An example:

class IsStringEqualButNotSame extends ArgumentMatcher {
    private String originalString;

    public IsStringEqualButNotSame (String originalString) {
	    this.originalString= originalString;
    }

    public boolean matches(Object value) {
	    return ((String)value).equals(originalString) && value != originalString;
    }
}
    String value = "Hello";
    verify(mockedlist).add(argthat(new IsStringEqualButNotSame(value));

This Matcher will match if a String is logically equal but the object is not the same. Not the best example :) but you can make Matchers this way.

Spying on real objects. You can spy a real object to verify interactions or to stub only one particular method. An example:

  List myList = new ArrayList<>()
  List myListSpy = spy(myList);
  myListSpy.get(5);    // will throw IndexOutOfBoundsException

  when(myListSpy.get(5)).thenReturn("Hello"); // will throw IndexOutOfBoundsException

If you stub a method like the example above the real method will still be called. You must use a slightly different syntax for this:

    doReturn("Hello").when(myListSpy.get(5));

Additional sources:

  • Mockito site
  • Mockito vs EasyMock
  • Not really related to Mockito. If you annotate a method with @Before this method will be called before every unittest in the class.
    If you annotate a method with @BeforeClass this method will only be called once. This method must be static.




    JPA Optimisitic locking versus Pessimistic locking

    Door: Peter Schuler, 14 January 2010

    As promised in my previous post I will blog some more about JPA and how to use it. In this post I will go into the locking features of JPA 2.0 including the new pessimistic lock options.

    This post will:

    • introduce the new locking features of the JPA;
    • introduce both pessimistic locking and optimitic locking concepts;
    • give a quick recap about JPA versioning;
    • talk about the connection between locking and design;
    • and finally compare both locking strategies.

    JPA 2.0 now supports Pessimistic Locking:

    A great omission of JPA 1.0 was the lack of pessimistic locking. Therefore it was necessary to fall back on the support of the underlying implementation to use the JPA is situation where pessimistic locking was required. This can happen when JPA shares a database with another process which does not know or supports versioning based optimistic locking.

    JPA 2.0 now supports the following locking modes:

    • OPTIMISTIC                                    (==READ in JPA 1.0)
    • OPTIMISTIC_FORCE_INCREMENT         (==WRITE in JPA 1.0)
    • PESSIMISTIC_READ
    • PESSIMISTIC_WRITE
    • PESSIMISTIC_FORCE_INCREMENT       (A hybrid of both strategies)
    • READ                                               (kept around for backward compatibility)
    • WRITE                                             (kept around for compatibility)

    Object can be locked by using the find() or refresh() operation of the EntityManager. For example:

    Order order = entityManager.find(Order.class, 10, LockModeType.PESSIMISTIC_READ);
     
    SELECT ID, PRODUCT, AANTAL, VERSION, orderId FROM ORDER_TABLE WHERE (orderId = ?) FOR UPDATE.

    As you can see the FOR UPDATE is added to the select query telling the database to get an exclusive lock on this selected row.

    You can also use the lock() method on the entityManager and specify a Lock Mode on Queries (JPQL / Named and Criteria).

    Now that we know how to unleash the power of pessimistic locking we need to learn how to use it well.

    Locking Strategies: a quick recap….

    Locking is a means to prevent data form becoming corrupted because two different processes are editing the same data. If we use locking correctly no two processes can edit (or if required) access the same data. Thus data can never be inconsistent.

    As already mentioned there are two locking strategies: optimistic locking and pessimistic locking. I will describe both strategies and give an overview of their pro’s and con’s.

    Pessimistic locking

    This strategy is the standard locking provided by the database. It will protect data by limiting access to a single process. This is achieved by keeping track of all the currently active locks. If another process wants to access locked data it will have to wait until the other process releases the lock. Of course this introduces a whole range of potential errors like lock timeouts and deadlocks.

    This locking strategy is called pessimistic because of the assumption that locking is always necessary to avoid corruption. Based on that assumption it introduces significant overhead in order to keep track of which process is assessing which data. Compare pessimistic locking to a traffic light. It will only allow vehicles to pass when it knows for sure that no one will be in the way.

    Using pessimistic locking has some pro’s:

    • The database is in charge and protects your data. Independent from application logic.
    • A process or thread can only proceed if it has the right locks. Thus it is guaranteed that there will be no conflicts once the lock is acquired.
    • Processes are put on hold until they can acquire the lock. (This blessing can also be a curse because a process can overwrite data the moment the lock is released. This feels like a missing update but is technically the correct behaviour. But as long as you read and write in the same transction you’re data is never stale.)

    No pro’s without con’s:

    • Keeping track of all those locks introduces significant overhead. Even if there is no data being accessed simultaneous the database still locks.
    • The locking can lead to deadlocks and lock time out. These errors are hard to recover from and take a long time before the calling process is informed.
    • Must be supported by the database.

    So pessimistic locking depends on the database restricting access to data. But this comes at high overhead and hard-to-recover errors.

    Optimistic locking

    As pessimistic locking is embedded in the DBMS, optimistic locking is a strategy that by-passes the database. It will detect conflicts only when they occur. This is done introducing a version number to every table you want to protect. If you read data you will get the version number. If you alter the data you first check the version number again, and when holding the previous read value, update the record and increment the version number. If some one has “changed the data right from under you” you will see a different version number and know that there is a conflict. I will refer to the optimistic lock procedure as check&update.

    This strategy is called optimistic because it never bothers to lock. It assumes that process will not bother each other until they do.

    Using optimistic locking has some big pro’s:

    • There is no (at least very little) overhead involved in locking.
    • Optimistic locking is fast and easy to use, especially because it works implicitly. If you specify a @Version the upate&check will be performed automatically.
    • It’s very efficient.
    • It is database independent. No special features are required.

    There are also some drawbacks:

    • It will only detect conflicts, not prevent them. When it occurs it’s the application that must resolve the conflict. For example by showing the user a diff or an option to override the current version in the database.
    • If a conflict occurs only one process is allowed to proceed. The others have their database transaction rolled back. This is far more expensive than waiting until you get the database lock.
    • It will only work if everyone accessing the database plays by the versioning rules. The database does not enforce it.
    • It can be considered ‘unfair’ as the process that writes the data first wins, opposed to the process that first acquired the lock.
    • Sometimes optimistic locking is not sufficient. Locking a complete table to protect against insert for example.

    So optimistic locking depends on the calling processes to respect the versioning rules. This makes it possible to detect conflicts and eliminates the need to keep of all the locks and gives Optimistic locking a huge advantage.

    However when conflicts occurs it is up to the application to patch things up.

    JPA support for optimistic locking

    JPA supports optimistic locking based on versioning right from the first release. All you need to do is declare an attribute of your class with a @Version annotation.

    For example:

      @Entity
      public class Order {
     
          @id @GeneratedValue
          private Integer id;
     
          @Version
          private Integer version;
    }

    The above code will result in a Order table with a primary key and version column. JPA will check and update the version after every change to Order.

    More on JPA versioning can be found here.

    Lock scope.

    At first glance versioning seems to be the preferred strategy. It’s easy to use and with little overhead. However there is one more aspect to take into account when dealing with locking. That is what I call ‘the lock scope’.

    Versioning will only lock (check&update) records that were changed. Databases will only lock records you tell it to lock by doing a SELECT … FOR UPDATE. Both procedures prevent processes from corrupting the database. But it will not prevent breaking business rules!
    Let’s look at the following example:

    This is a typical Order->OrderLine example. Order has a set of OrderLines which keep a price and quantity for every single item in Order. Let’s assume that there is a business rule that the total amount of money of an Order must stay below $10.000. This is easily achieved by adding a check on order to make sure that every addition/alteration of OrderLines will not break this rule.
    A problem occurs when another process comes in and adds OrderLines to an Order at the same time. No single process knows all OrderLines. To make the check work in a concurrent environment you need to make the OrderLine updates in a serial order. In other words: the Order needs to be locked before any additions can be made to OrderLines. This ensures that the business rule can be enforced.

    The JPA can achieve this by using one of the two lock levels: OPTIMISTC_FORCE_INCREMENT or PESSIMITC_WRITE. Both will give you a exclusive lock to make sure no other process can edit the same data.

    This example illustrates that there are situations in which you need to think ahead about locking. Both versioning and database locks won’t help you out-of-the-box . You need to determine the right lock scope. Determining the lock scope is a business question and needs to be defined based on the functional design and then translated to technical requirements.

    Choosing a locking Strategy.

    Ok .. now you know about the pro’s and con’s of both locking strategies. You know how to use them technically and you know you need to think about the lock scope. So which strategy is for winners?

    As you probably have guessed there is no straightforward answer.

    Optimistic locking has little overhead and is easy to use, especially because it works implicitly in JPA. But you need to make sure that everyone using the database uses the same versioning approach. It’s also more expensive in terms of conflict resolving.

    Optimistic locking is the preferred strategy if:

    • You’re application has a private database.
    • All the applications using the database know and use versioning.
    • It is unlikely that there will be a lot of conflicts. (eg. Users editing the same data.)

    Pessimistic locking will protect data on the database level. It will prevent conflicts by putting the process in a queue to wait for the lock. If there are a lot of collisions this gives a better change of more processes making it through. However having to keep a large lock administration involves a lot of overhead even if there a no conflicts.

    So pessimistic locking it the preferred strategy if:

    • Other non-versionized processes will edit the data you need to lock.
    • You predict / see that there will be a lot of colissions.

    For those among us unable to choose, JPA offers a hybrid solution. If you use the lock option PESSIMISTIC_FORCE_INCREMENT both Pessimitic and Optimisic locks are acquired at the same time. Offcourse you’re cutting of both your hands when using this option for every database call…. “Just to be sure .. “. You’ll end up with the bad from both locking strategies. But this hybird option can be a life saver when a particular table or operation must be protected at a database level and still has to participate in versionized transactions.

    More information on locking

    And don’t forget to think about the lock scope!

    This is the second installment of my blogs about the JPA. Next time we’ll go into the new Criteria API of JPA 2.0.

    • Special thanks to Martijn Blankestijn for the Order example and Jouke Stoel for test reading.