Tag Archives: java

Programming Basic: Java Multithreading

Multithreading is probably the trickiest basic programming concept to learn. To start with, let’s ask why do we even need multiple threads?

Well, think about stuff you do on daily basis. You’re hungry and you need to cook dinner, so you grabbed a frozen pizza off the fridge and pop it to the oven. And then you realize you have to iron your shirts so you can use them for work next week. You wouldn’t stand idle in your oven while it’s cooking right? You’d typically make the most of your time and iron the shirts while pizza is cooking in the oven. The way your program should work is similar, it shouldn’t waste time idling if it can do something else.

Now let’s say I have these two methods:

[sourcecode language="java"]

static void bakePizza() {

for(int i=0; i<3; ++i) {
System.out.println("Baking pizza");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

System.out.println("Baking pizza done");
}

static void ironShirt() {

for(int i=0; i<3; ++i) {
System.out.println("Ironing shirt");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

System.out.println("Ironing shirt done");
}
[/sourcecode]

For time being don’t worry so much about Thread.sleep(..), just assume it’s there to put 1000 milliseconds (1 second) delay on the code execution. Each method (task) cost about 3 seconds to run. If we call these two functions in order it’s going to cost about 6 seconds.

[sourcecode language="java"]
public static void main(String[] args) {
bakePizza();
ironShirt();
System.out.println("Let’s call it a day");
}
[/sourcecode]

If you run the code above, your output will look like following:

[sourcecode]
Baking pizza
Baking pizza
Baking pizza
Baking pizza done
Ironing shirt
Ironing shirt
Ironing shirt
Ironing shirt done
Let’s call it a day
[/sourcecode]

Now in order to bake pizza and iron your shirts in parallel, we need to run them in a separate Thread. In Java, your main method always runs in the a thread called main thread. A thread is represented by the Thread class. There’s many way to create a thread, here I’ll use an anonymous class extending the Thread class:

[sourcecode language="java"]
Thread bakingPizzaThread = new Thread() {
public void run() {
bakePizza();
}
};

bakingPizzaThread.start();
[/sourcecode]

As soon as you call the start method on your thread object, Java will invoke the run method on a new thread — and your main thread continue its execution. In other word the main thread will not wait until pizza baking is finished.

In below example I run bakePizza() and ironShirt() both in its own thread, this is what I get (result may vary, but notice how the code now only runs for roughly 3 seconds rather than 6. This is because both long running method can be executed simultaneously

[sourcecode language="java"]
public static void main(String[] args) {
Thread bakingPizzaThread = new Thread() {
public void run() {
bakePizza();
}
};

Thread ironingShirtThread = new Thread() {
public void run() {
ironShirt();
}
};

bakingPizzaThread.start();
ironingShirtThread.start();

System.out.println("Let’s call it a day");
}
[/sourcecode]

[sourcecode]
Let’s call it a day
Baking pizza
Ironing shirt
Baking pizza
Ironing shirt
Baking pizza
Ironing shirt
Baking pizza done
Ironing shirt done
[/sourcecode]

 

Handling Heavy-lifting Job Using Thread Pooling

Your java app server such as Tomcat, JBoss, Websphere and Glassfish are multithreaded — meaning if a user opens a web page (HTTP request submitted), the app server will try to find a free unused thread, and allocate the job of serving the request to it.

One common problem which I recently come accross is when the user performs a long-running task such as reporting or data transformation. If you just simply allow a user to execute a long-running task, your app server is vulnerable to thread starvation — that is genuine user load, or even hackers can issue a massive amount of request causing your server to run out of free threads — hence denying application availability.

One approach is to implement a resource bounding pattern such as thread pooling. The analogy of this pattern is similar like a chef in a restaurant. Say if there is 2 chefs on a restaurant, and each one of them needs 10 minutes to cook an order. Each next free chef will take the order in the order that it arrives, and if all two of them are busy, subsequent order will be queued .

To illustrate this with an example, following is a class that represent a long-running task. Here the task is simply performing 10 seconds delay to simulate the long-run. A log message with task id and the name of the thread running the task is printed when the task begins and ends.

[sourcecode language="java"]
public class HeavyTask implements Runnable {
private static Logger logger = LoggerFactory.getLogger(HeavyTask.class);
private int taskId;

public HeavyTask(int taskId) {
this.taskId = taskId;
}

public void run() {
logger.info(String.format("Task #%s is starting on thread %s…", taskId, Thread.currentThread().getName()));

try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
logger.error(String.format("Task #%s running on thread %s is interrupted", taskId, Thread.currentThread().getName()), e);
}

logger.info(String.format("Task #%s on thread %s finished", taskId, Thread.currentThread().getName()));
}
}
[/sourcecode]

Secondly we have the HeavyTaskRunner class which is a service class that implements business functionality. This class also instantiates the thread pool using Java ExecutorService API with 2 maximum threads by using Executors.newFixedThreadPools() factory method.

[sourcecode language="java"]

public class HeavyTaskRunner {
private ExecutorService executorService;
private static final int NUM_THREADS = 2;
private int taskCounter = 0;

public HeavyTaskRunner() {
executorService = Executors.newFixedThreadPool(NUM_THREADS);
}

/**
* Create a new { HeavyTask} and submit it to thread pool for execution
*/
public int runTask() {
int nextTaskId;
synchronized(this) {
nextTaskId = taskCounter++;
}
executorService.submit(new HeavyTask(nextTaskId));
return nextTaskId;
}
}
[/sourcecode]

And finally I wrapped this in a nice simple Spring MVC web application. You can download the source code from my google code site and run embedded tomcat container using mvn tomcat:run command.

If you look at the server log, this is what it prints after 4 tasks were run in less than 10 seconds. Notice that not more than 2 tasks ever run simultaneously. If all threads are busy the task will be queued until one become free:

This techniques is ofcourse not without downside. Although we have capped the thread (an memory) resource into certain limit, the queue can still grow infinitely, hence our application is still vulnerable to denial of service attack (if a hacker submitted long running tasks for a thousand time, the queue will grow very big causing service unavailability to genuine users)

The concurrency chapter of Java SE tutorial is a good reference if you want to dig more into other techniques of managing threads and long running tasks.

Demo Application Source Code

Source code for the demo application above is available for browsing / checkout via Google Code hosting:

  • Browse: 
  • Checkout:

Ensure you have latest version of JDK and Maven installed. You can run the application using embedded tomcat with mvn tomcat:run command from your shell.

When Your JVM Crashes With OutOfMemoryError

Getting OutOfMemoryError: java heap space is probably one of the most annoying thing to happen to your application server. As application gets more complex and your boss keep pushing you to implement new functionality faster, it’s easy to forget about heap consumption efficiency

Fortunately there are few things you can do to analyze the root cause, and attempt to solve the issue. I stumbled upon a little useful JVM option -XX:+HeapDumpOnOutOfMemoryError when digging Oracle Hotspot VM documentation. What this option will do is to generate a heap dump file something like java_pid1234.hprof right before the java process terminates. You can then load this file into an analysis tool like jvisualvm to have a look at what’s going on.

Let’s give this a go!

Let’s write a tiny little program that leaks a huge amount of memory (let’s hope none of your programmer colleague does anything like this)

[sourcecode language="java"]
public class LittleLeaker {

/**
* A little piece of program that leaks a lot of memory
*/
public static void main(String[] args) {
ArrayList array = new ArrayList();

while (true) {
array.add("Let’s leak some memory here");
}
}

}
[/sourcecode]

Compile it, and run the code with following command

[sourcecode language="text"]
java -XX:-HeapDumpOnOutOfMemoryError LittleLeaker
[/sourcecode]

You shouldn’t have to wait too long until your VM gave up and throw OutOfMemoryError. When it does, notice the hprof file that got created:

[sourcecode language="text"]
192-168-1-3:bin gerrytan$ java -XX:+HeapDumpOnOutOfMemoryError LittleLeaker
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid280.hprof …
Heap dump file created [92624139 bytes in 0.306 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2760)
at java.util.Arrays.copyOf(Arrays.java:2734)
at java.util.ArrayList.ensureCapacity(ArrayList.java:167)
at java.util.ArrayList.add(ArrayList.java:351)
at LittleLeaker.main(LittleLeaker.java:28)
[/sourcecode]

Let’s Analyze The Heap Dump File

  1. Make sure you have the latest JDK installed and configured on your PATH environment variable. Run jvisualvm program on command line. If this is the first time you’re running it, it might perform some calibration first.
  2. Load the hprof file by using the menu File -> Load. Select the file format to “Heap Dumps” and point to the path of the hprof file generated earlier
  3. Once loaded, you can see some basic information like when was the dump taken, environment properties, system properties, but most importantly the Threads at the heap dump section. Click the Show Threads link underneath it

    Recall that your virtual machine is a multithreaded environment. In our case, since it’s just a very simple app, you would be interested in the “main”thread.You can trace down in the main thread stack trace the culprit of the OOME.You might be thinking this is not so cool because you’ve already seen the stack trace from the console anyway. But think about if this were your Java EE app server with dozens of threads, getting to know what other threads are doing will be handy
  4. Another interesting analysis to perform is the Classes button at the top. This will show you total number of instances in the heap per classes

    As you can guess, this might not look so interesting since our program is just very simple. But when you have a real ly-complex enterprise application, then this information will be very helpful

There Are Heaps Other Tricks and Techniques

The functionality of Jvisualvm doesn’t stop there. You can also attach it to running JVM to see live monitoring data, obtain thread dump, profiling and plenty others.

This article written by Oracle’s Mandy Chung is a very good reading to deepen your knowledge about java application monitoring.

Mapping JSON Request With Spring MVC

Inspired by , this is a short tutorial on how you can map a request with *.json extension into a JSON view.

This tutorial will demonstrate a small subset of Spring JSON capability using the ‘Spring MVC Project’ template application generated by STS. When you first created a new project from the template, the web app came with a default home page showing ‘Hello World’ and a server time passed via Model attribute.

We will extend this home page a little bit so we can obtain the JSON view. Note that the JSON view will only contain the formatted attributes inside the Model object

By the way, if you haven’t already know — JSON stands for Java Script Object Notation. It’s a textual representation of a Java Script object, and it’s one of the most popular way of transferring information from server to client in modern Ajax application.

Create a new project using a template

  1. Assuming you have SpringSource Tools Suite (STS) installed, create a new project and select Spring Template Project Wizard
  2. Select ‘Spring MVC Project’ from the selection of template, it might prompt you to download if this is the first time you’re using it
  3. Enter a project name and top-level package and hit ‘Finish’

Change the view resolver to ContentNegotiatingViewResolver

ContentNegotiatingViewResolver is a unique resolver which will delegate request to another resolver by the requested media types. There are multiple way it can determine the media type, but here we’ll just use the URL extension method (see the javadoc for more).

On the servlet spring beans configuration (servlet-context.xml), replace the default InternalResourceViewResolver with this:

[sourcecode language="xml"]
If the request has an extension .json, always provide MappingJacksonJsonView regardless –>




















[/sourcecode]

In the example above, we define request with the extension “.*json” into “application/json” media type. Normal request is set to “text/html” by the browser by default. When a request came, the list of view resolvers on the “viewResolver” property will be consulted, and if it supports the requested  media type, that view resolver will be used.

The “defaultViews” property specifies the view that will be override the ones provided by matching resolvers (even if none matches) — regardless of the view name returned by the controller. This however only hold true if the View supports the requested media type.

For example, if “/home” path is requested with Accept header “text/html”, ContentNegotiatingViewResolver will set the media type to “text/html”, consult InternalResoursceViewResolver bean (which supports text/html) and use it. If “/home.json” path is requested, the media type is set to “application/json” (not supported by InternalResourceViewResolver), and since the specified default view MappingJacksonJsonView supports it, it will be used. This is sufficient for common usage because all JSON view can be rendered in the same fashion

Have a look at for more info.

Change the Controller mapping

STS Spring MVC new project template mapped the MainController into “/”, however for our demonstration purpose, let’s map it to “/home”, so we can compare the different media type easily.

[sourcecode language="java"]
/**
* Handles requests for the application home page.
*/

public class HomeController {

private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

/**
* Simply selects the home view to render by returning its name.
*/
(value = "/home", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! the client locale is "+ locale.toString());

Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);

String formattedDate = dateFormat.format(date);

model.addAttribute("serverTime", formattedDate );

return "home";
}

}
[/sourcecode]

Add Jackson dependency to your classpath

The MappingJacksonJsonView requires Jackson library in your classpath. This library will help you to transform java objects into JSON representation. Add the following dependency to your pom.xml

[sourcecode language="xml"]

org.codehaus.jackson
jackson-mapper-lgpl
1.2.1

[/sourcecode]

Ready to go

Fire up embedded tomcat using mvn package tomcat:run goals, and:

  1. Point your browser to http://localhost:8080/json-simple/home. Inspect you are getting the normal hello world page with server time
  2. Point your browser to http://localhost:8080/json-simple/home.json. Inspect you are getting the json representation of the model object

The sourcecode for this tutorial is available:

  • For browsing: http://code.google.com/p/gerrytan/source/browse/#svn%2Ftrunk%2Fjson-simple
  • For checkout: /json-simple

Building a JBoss Ready Spring MVC Web App

Spring is a really cool J2EE extension framework incorporating and techniques, and JBoss is one of the first open-source J2EE container well-known in the community. However building a Spring based application to fit for a JBoss deployment isn’t always a straightforward task.

Spring provides an easy-to-use rapid code generation tool called “Spring Roo” so you don’t have to start from scratch to achieve most of the configuration plumbing. However the code generated by Roo assumes a minimalistic web container (such as tomcat) where almost all Java EE API modules are deployed on the application side — not on the container.

Although this topic is still widely open for discussion, the benefit of using a container managed modules includes ease of configuration, operation and maintenance. For example if you deploy your datasource on JBoss, it would provide you with the connection pool usage statistics.

This guide demonstrate process of developing a simple Phonebook application where user can list and add contacts. Following are the goals we’re trying to achieve:

  • Spring-based application generated by Spring Roo which should be suitable to deploy to JBoss container.
  • Minimal (none if possible) JBoss customization. The web-app we’ll create should deploy straight into a fresh-install JBoss container. Only stuff like datasources should need configuration on JBoss
  • Use JBoss provided Java EE API modules whenever possible. The JBoss server profile we’ll use is ‘default’ which already provide a lot of stuff, including servlet, JSP, JSTL, EL, JTA, EJB3, JPA and Hibernate.

This guide and the demo source code is written against following versions:

  • JBoss 6.0.0.Final & 7.1.1.Final
  • Spring Roo 1.2.2.RELEASE
  • JDK 6
  • Apache Maven 3.0.3

Let’s Start the Rapid Code Generation

Start the Spring Roo shell (either via command line or your favourite IDE) and use following commands:

  1. Create new war project. Adjust project name and top level package to your liking. IDE such as eclipse provide a dialog box to create a new project, feel free to use it instead.
     project --topLevelPackage com.wordpress.gerrytan.springjboss --projectName spring-jboss --packaging war 
  2. Setup JPA persistence. JBoss came with pre-installed HSQL datasource available via JNDI under the name java:/DefaultDS, so we’ll leverage this. Feel free to install and use another database if you want to. (If you use JBoss 7, the sample datasource JNDI name is java:/jboss/datasources/ExampleDS)
     jpa setup --database HYPERSONIC_PERSISTENT --provider HIBERNATE --jndiDataSource java:/DefaultDS 

    After you run this command, Roo will create a Spring applicationContext.xml configuration file that will scan and contain your data and business layer beans and JPA persistence.xml persistence unit configuration.

  3. Setup Spring MVC controller. If this is the first time you hear about Spring MVC, you might want to read their manual (or keep going — trust me, Spring MVC provides a powerful API for your web-app :) )
     web mvc setup 

    After you run this command Roo will create a web.xml with Spring MVC DispatcherServlet configured, and a webmvc-config.xml that will scan and contain your Controller beans. Note that the webmvc-config.xml context will be set as a child of applicationContext.xml context so that your data layer beans will be instantiated first, and then injected to your controller beans. Roo will also configure JSP + Apache Tiles based views for you which we’ll cover later.

Great! At this point you have almost all the boilerplate and plumbing you need to start writing your web-app.

Start Writing the Web App

The small web app we’re going to write has one page with two panels, one for add-contact form, and the other for listing and deleting contacts:

  1. Create a new Contact entity with firstName, lastName and phoneNumber fields. We’ll again leverage Roo to do this. Issue following command on a Roo shell:
    entity jpa --class ~.Contact
    field string --fieldName firstName --notNull
    field string --fieldName lastName --notNull
    field string --fieldName phoneNumber --notNull
    
  2. Create (manually) a new Controller. I won’t use Roo this time because the controller code generation feature of Roo provides us more than we need, so we’ll just create a simple Spring MVC controller here. The controller has all handlers method to perform addition, listing and deletion. if this is the first time you see it.
    
    ("/contact")
    public class ContactController {
    
      (method = RequestMethod.GET)
      public String get(("newContact") Contact contact) {
        return "contact/index";
      }
    
      (method = RequestMethod.POST, params="deleteId")
      
      public String delete( long deleteId) {
        Contact contact = Contact.findContact(deleteId);
        contact.remove();
        return "redirect:/contact";
      }
    
      (method = RequestMethod.POST)
      public String add(("newContact")  Contact contact, BindingResult bindingResult) {
        if (!bindingResult.hasErrors()) {
          contact.persist();
          return "redirect:/contact";
        }
        return "contact/index";
      }
    
      ("contacts")
      public List getContactList() {
        List result = Contact.findAllContacts();
        return result;
      }
    }
    
  3. Create the view, we’ll leverage the Apache Tiles API provided by Roo. Tiles adds much-needed templating and inheritance feature to JSP so it’s easy for you to reuse parts of your presentation code in multiple place. Have a look at their manual page for more info. Create a jspx file src/main/webapp/WEB-INF/views/contact/index.jspx which will contain our jsp view presentation code to list Contacts and add a new one:
        
    
        
    First Name Last Name Phone Number
        
    You have no contacts in your phone book. Add a new contact using the form above.
    Id First Name Last Name Phone Number
    ${contact.id} ${contact.firstName} ${contact.lastName} ${contact.phoneNumber}
        
    

    And create a views.xml tiles configuration file. This file contains metadata information about template, inheritance, and other tiles feature. Since this is just a simple web-app, I’m not superclassing any other page or template, but just create a new standalone jsp page

    
      
      
    
    

That’s about all the code we’ll need for this web-app. Now is the slightly tricker part, plumbing Spring into JBoss.

EntityManagerFactory Plumbing

When you setup JPA using Roo, it gives you a Spring-managed persistence unit via . However when you deploy your app to JBoss, the presence of META-INF/persistence.xml also causes JBoss to create its own persistence unit, causing conflict. Of course you can if you want, but the approach we’ll take here is to use the JBoss provided:

  1. Configure the JNDI name of the JBoss-provided persistence unit. Add following element to your web.xml. persistence/spring-jboss-emf will be the JNDI name of the JBoss provided persistence unit, and persistenceUnit is the name Roo give to the persistence unit configuration file (META-INF/persistence.xml)
      
        persistence/spring-jboss-emf
        persistenceUnit
      
    
  2. Replace LocalContainerEntityManagerFactoryBean with JNDI lookup on applicationContext.xml
    
    
    
  3. Let the persistence unit know what the datasource JNDI name is. We’ll just use the sample HSQL datasource which came with out-of-the-box JBoss install (java:DefaultDS on JBoss 6 and java:jboss/datasources/ExampleDS on JBoss 7). Add element to your META-INF/persistence.xml file:
    
            org.hibernate.ejb.HibernatePersistence
            java:DefaultDS
                
    
    

    We didn’t have to do this with Spring-managed persistence unit because LocalContainerEntityManagerFactoryBean already done it for us. Change java:DefaultDS into java:jboss/datasources/ExampleDS if deploying into JBoss 7.

  4. And since we already done step 3, we no longer need to keep the datasource bean on applicationContext.xml. Feel free if you want to keep it though
      

Maven Fine Tuning

We’re nearly there. This last bit is related to Maven (the build, packaging, and dependency management tool):

  1. (Only if you use eclipse) Change java.version properties on pom.xml from 6 into 1.6. You might not need to do this but I use eclipse and somehow I couldn’t get it to run in jdk 6 mode unless I change it. Right click on your project –> choose Maven –> Update project configuration once you’ve done this
  2.  Change the scope of following Maven dependencies into “provided”. These are the dependencies that will be provided by JBoss, so unless you mark it as so, Maven will include it on the war file (and potentially causing classpath conflict)
    hibernate-core
    hibernate-entitymanager
    hibernate-jpa-2.0-api
    hibernate-validator
    validation-api
    jta
    jstl-api
    jstl-impl
    slf4j-api
    slf4j-log4j12
    log4j
    jcl-over-slf4j
    

    You can change the scope of a dependency by adding provided element. The default if not provided is “compile”

        
          org.hibernate
          hibernate-core
          3.6.9.Final
          provided
        
    

Compile, Deploy and Cross Your Fingers

Here comes the moment of truth!

  1. Run mvn clean package command to compile and package your war file. Once it completes you will get a target/spring-jboss-1.0-SNAPSHOT.war file. Deploy this file by placing it to your %JBOSS_HOME%serverdefaultdeploy folder
  2. Start your JBoss server
  3. Open http://localhost:8080/spring-jboss-1.0-SNAPSHOT/contact on your web browser
  4. Enjoy your JBoss-ready Spring MVC web-app :)

Check the Demo Sourcecode

The demo sourcecode for this blog post is available here:

  • For source code browsing: 
  • For svn checkout:

Note that if your code output some logging content, it’s best to use the slf4j logging API. Slf4j provides an abstraction of all other available logging APIs so your code will still work regardless of which logging implementation is used.

It Doesn’t Work!

Relax, it does take time to get everything in place. Here are few tips for troubleshooting JBoss deployed Spring web app (apart from the obvious: inspecting the exception, stack trace, logs, etc):

  1. Review all the ‘plumbing’ work, make sure there’s no leak on the pipe! Following are the list of all the configurations file we’ve touched in this guide:
    pom.xml
    src/main/resources/META-INF/spring/applicationContext.xml
    src/main/resources/META-INF/persistence.xml
    src/main/web-app/WEB-INF/spring/webmvc-config.xml
    src/main/web-app/WEB-INF/web.xml
    
  2.  Review the jars included inside your war file against the one provided by JBoss. If you think you’re packaging something already provided by JBoss, maybe you should mark the dependency as “provided”
  3. Consult the manuals, reference guide, and ask the community

Declarative Transaction Boundary using Spring

One of the trickiest thing to do when developing database-backed application is deciding when and where to start and finish the transaction (eg: where should you draw the transaction boundary line).

Consider a very simple banking application with an AccountService class having getBalance(), debit(), credit() and transfer() methods. Transfer() calls getBalance() to validate the from-account has enough money, and then debit() the from-account and credit() the to-account.

All of the business steps of transfer() method have to be done in one transaction right? (why? — c’mon.. if you don’t do it in one transaction then it’s possible the balance got changed by another transaction between checking for sufficient money, debiting & crediting. The bank will lose reputation and have apologize to the poor customer.).

Pseudocode/sql for each method on AccountService class look somewhat like following:

  • getBalance()
    SELECT balance FROM account WHERE id = ?
  • debit() and credit()
    UPDATE account SET balance = ? WHERE id = ?
  • transfer()
                 if (getBalance(fromAccount) < amount) {
                   /*insufficient balance error */;
                 }
                 debit(fromAccount, amount);
                 credit(toAccount, amount);
               

If you programatically hard-code the transaction boundary into getBalance(), debit() and credit() method, then it might look something like this:

  public void debit(long accountId, double amount) {
    em.getTransaction().begin(); // start a new transaction
    Account account = em.find(Account.class, accountId);
    account.setBalance(account.getBalance() - amount);
    em.getTransaction().commit(); // commit
  }

But hangon, now you need to invoke all those 3 methods within 1 single transaction, your code might need to do something more complicated than that. If you change the transaction boundary into the transfer() method, then other clients that have been using getBalance(), debit(), credit() methods happily for other stuffs will be impacted — they now have to manually open and close transaction before calling those method (ugly).

Even worse, you may be considering to copy & paste the inside of getBalance(), debit() and credit() code into the transfer() method.. PLEASE DON’T!.. Remember Don’t Repeat Yourself principle!

Fortunately Spring provides a much better way of figuring out transaction boundary. All you need to do is to declare that your method needs an active transaction to be open. You do this by adding annotation to your method, plus bootstrapping few configurations

Your AccountService methods look like following now:

  
  public double getBalance(long accountId) {
     // do stuff here
  }

  
  public void debit(long accountId, double amount) {
    // do stuff here
  }

  
  public void credit(long accountId, double amount) {
    // do stuff here
  }

  
  public void transfer(long fromAccountId, long toAccountId, double amount) {
    // call getBalance(), check from account has enough money

    // call debit()

    // call credit
  }

And the magic happens! When you call the transfer() method, Spring detects you don’t have an open transaction, so it creates a new one. When transfer() calls getBalance(), Spring won’t create a new transaction because it detects there’s a currently open one. It will assign the open transaction into getBalance() method instead. The same applies to debit() and credit(). This is also known as Transaction Propagation.

Spring does this magic via a technique called AOP (Aspect Oriented Programming). Simply speaking, Spring transaction manager will be notified everytime annotated method is invoked / returned, and take action (start new transaction, assign existing one, close, etc.)

I’ve created a demo project with a unit test so you can try this yourself. Make sure you have jdk 1.6 and Maven 3 installed. SVN Checkout , have a feel around the classes and run mvn test. The output will be available at target/surefire-reports/com.wordpress.gerrytan.springtx.AccountServiceTest-output.txt. I’ve configured the logging such that you can see when hibernate (JPA) creates / commit / rollback transaction, and issues SQL to synchronize the persistence context.

2012-05-31 01:06:26,430 [main] DEBUG com.wordpress.gerrytan.springtx.AccountServiceTest - ----- Transfer $20 from account 2 to 1 -----
2012-05-31 01:06:26,430 [main] DEBUG org.hibernate.transaction.JDBCTransaction - begin
2012-05-31 01:06:26,431 [main] DEBUG org.hibernate.transaction.JDBCTransaction - current autocommit status: true
2012-05-31 01:06:26,431 [main] DEBUG org.hibernate.transaction.JDBCTransaction - disabling autocommit
2012-05-31 01:06:26,431 [main] DEBUG org.hibernate.SQL - select account0_.id as id0_0_, account0_.balance as balance0_0_, account0_.name as name0_0_, account0_.version as version0_0_ from account account0_ where account0_.id=?
2012-05-31 01:06:26,432 [main] DEBUG org.hibernate.SQL - select account0_.id as id0_0_, account0_.balance as balance0_0_, account0_.name as name0_0_, account0_.version as version0_0_ from account account0_ where account0_.id=?
2012-05-31 01:06:26,433 [main] DEBUG org.hibernate.transaction.JDBCTransaction - commit
2012-05-31 01:06:26,437 [main] DEBUG org.hibernate.SQL - update account set balance=?, name=?, version=? where id=? and version=?
2012-05-31 01:06:26,437 [main] DEBUG org.hibernate.SQL - update account set balance=?, name=?, version=? where id=? and version=?
2012-05-31 01:06:26,438 [main] DEBUG org.hibernate.transaction.JDBCTransaction - re-enabling autocommit
2012-05-31 01:06:26,438 [main] DEBUG org.hibernate.transaction.JDBCTransaction - committed JDBC Connection
2012-05-31 01:06:26,438 [main] DEBUG com.wordpress.gerrytan.springtx.AccountServiceTest - ----- Completed Transfer $20 from account 1 to 2 -----

Following are useful resources for further learning:

Various States of JPA Entities

EntityManager is the probably the most important class you need to know when writing your JPA data layer. In some way, you can think of EntityManager like your nice trustworthy dentist. The very first time you go to your dentist, he doesn’t know anything about you, so you’ll have to register and fill in a form. Once your dentist has finished filling that hole in your tooth, he’ll probably note couple things in your patient record and file it. You would then go home, your dentist wouldn’t know what you are doing afterwards and in few weeks when you came back he would ask if any of your medical condition had changed since and update the record.

The way JPA EntityManager work is quite similar. Following is a picture of various states a JPA entity can be, and method that transitions from one state into another.

Different states of a JPA entity

When a new entity object is created in the java memory, the entity manager had no idea about it. This entity object is called to be in new (transient) state. Entity manager wouldn’t care with whatever change you made to the object.

When you call the entity manager’s persist() method over the object, it saves the state of the object into the persistent storage (typically database), and starts to care about changes you make to it. The entity object is now in managed state. If you modify the state of the object, entity manager will synchronize the state back to the persistent storage. Synchronizing state back into persistent storage typically means issuing necessary SQL statement so the state of the object matches the ones on the database. Entity manager will not issue SQL statement immediately all the time, but only at “flush time”.

The specifics of when entity manager performs flushing differs between various JPA implementation, but here is what Hibernate documentation says:

Flush occurs by default (this is Hibernate specific and not defined by the specification) at the following points:

  • before query execution
  • from javax.persistence.EntityTransaction.commit()
  • when EntityManager.flush() is called

It’s also pretty common for the entity object to lose contact with entity manager even after it’s managed. This typically happen when the entity manager is closed, or the object leaves the java memory (eg being transferred to a web browser screen). An entity object which was once persistence but no longer is is called to be in detached state.

An object which is in detached state can be put back into managed state by calling merge() method. Entity manager will typically try to identify the object by its primary key, and perform DML statements such as UPDATE to synchronize the persistent state.

If a lot of changes need to be done to the object’s state, a common technique is to do this while the object is in detached state, and then reattach it later, thus we can avoid costs of issuing SQL statement during the changes.

Finally an entity object in managed state can be marked for removal, and this object is called to be in removed state.

is a good reading if you want to learn more about JPA state.

Persisting Data Using JPA

If you ever written a Java application that reads and updates into a relational database in the past, most likely you’ll use the JDBC API. Typically you’ll need to represent the database entity as a java object, and write a service/DAO class to provide CRUD (Create Read Update Delete) facility.

Dealing with persistent data became more tricky when the number of entity types keep growing, and also their complexity of relationships. The amount of code keep growing, and it became harder and harder to maintain. More recently, the better approach is to use ORM (Object Relational Mapping) solution such as Hibernate. With the popularity of ORM techniques, the Java community has also introduced JPA (Java Persistence API) which is a standardized ORM API. Hibernate is one of the popular JPA implementation available.

To give a basic idea, consider following simple example about a book entity. A book is identified by book id, and has author, title and year property.

public class Book {
        private int bookId;
        private String title;
        private String author;
        private int year;

        public Book() {}

        public Book(int bookId, String title, String author, int year) {
                this.bookId = bookId;
                this.title = title;
                this.author = author;
                this.year = year;
        }

        // Getters and setters omitted for brevity
}

Let’s create a DAO to provide CRUD facility over book entity. The DAO is implemented as an interface so it doesn’t need to know what the underlying mechanism used. Later we’ll implement the BookDAO interface using both Jdbc and JPA to compare the difference

public interface BookDAO {
        /**
         * Find a book by id
         *  null if can't find bookId
         */
        public Book findById(int bookId);

        /**
         * List all books
         */
        public List list();

        /**
         * Persist a new book object into database. The id attribute of the book object will be set
         * and returned.
         *  id of the newly inserted book
         */
        public int save(Book book);

        /**
         * Persist changes to existing book object into database.
         *  book
         */
        public void update(Book book);

        /**
         * Remove persisted book object from database
         *  book
         */
        public void delete(Book book);
}

Following is example on how to implement BookDAO using plain JDBC. This implementation simply opens and closes connection for every method calls, assuming a connection pooled datasource is used. Note how we have to manually construct our CRUD SQL and map the ResultSet object returned by JDBC.

/**
 * Implementation of BookDAO using jdbc, creates and close a new connection for every
 * CRUD method calls. Use connection pooled datasource for efficiency.
 *
 *  gerry
 *
 */
public class BookJdbcDAOImpl implements BookDAO {

        private DataSource dataSource;

        public BookJdbcDAOImpl (DataSource dataSource) {
                this.dataSource = dataSource;
        }

        
        public Book findById(int bookId) {
                Connection connection = null;
                try {
                        connection = dataSource.getConnection();
                        Statement statement = connection.createStatement();
                        ResultSet rs = statement.executeQuery("SELECT * FROM book WHERE book_id = " + bookId);
                        if (!rs.next()) {
                                return null;
                        }
                        Book result = mapRow(rs);
                        statement.close();
                        return result;

                } catch (SQLException e) {
                        throw new RuntimeException(e.getMessage(), e);
                } finally {
                        try {
                                connection.close();
                        } catch (SQLException e) {
                                throw new RuntimeException(e.getMessage(), e);
                        }
                }

        }

        
        public List list() {
                Connection connection = null;
                try {
                        connection = dataSource.getConnection();
                        Statement statement = connection.createStatement();
                        ResultSet rs = statement.executeQuery("SELECT * FROM book");
                        ArrayList result = new ArrayList();
                        while (rs.next()) {
                                result.add(mapRow(rs));
                        }
                        statement.close();
                        return result;
                } catch (SQLException e) {
                        throw new RuntimeException(e.getMessage(), e);
                } finally {
                        try {
                                connection.close();
                        } catch (SQLException e) {
                                throw new RuntimeException(e.getMessage(), e);
                        }
                }
        }

        
        public int save(Book book) {
                Connection connection = null;
                try {
                        connection = dataSource.getConnection();
                        Statement statement = connection.createStatement();
                        statement.executeUpdate(
                                String.format("INSERT INTO book (title, author, year) VALUES ('%s','%s',%s)",
                                        book.getTitle(),
                                        book.getAuthor(),
                                        book.getYear()),
                                Statement.RETURN_GENERATED_KEYS);
                        ResultSet rs = statement.getGeneratedKeys();
                        if (!rs.next()) {
                                throw new IllegalStateException("Error when inserting book to database " + book);
                        }
                        int generatedKey = rs.getInt(1);
                        book.setBookId(generatedKey);
                        statement.close();
                        return generatedKey;
                } catch (SQLException e) {
                        throw new RuntimeException(e.getMessage(), e);
                } finally {
                        try {
                                connection.close();
                        } catch (SQLException e) {
                                throw new RuntimeException(e.getMessage(), e);
                        }
                }
        }

        
        public void update(Book book) {
                Connection connection = null;
                try {
                        connection = dataSource.getConnection();
                        Statement statement = connection.createStatement();
                        int rowUpdated = statement.executeUpdate(
                                        String.format(
                                                "UPDATE book " +
                                                "SET title = '%s', " +
                                                "author = '%s', " +
                                                "year = %s " +
                                                "WHERE book_id = %s",
                                                book.getTitle(),
                                                book.getAuthor(),
                                                book.getYear(),
                                                book.getBookId()));
                        if (rowUpdated != 1) {
                                throw new IllegalStateException("Error when trying to update " + book);
                        }
                        statement.close();
                } catch (SQLException e) {
                        throw new RuntimeException(e.getMessage(), e);
                } finally {
                        try {
                                connection.close();
                        } catch (SQLException e) {
                                throw new RuntimeException(e.getMessage(), e);
                        }
                }

        }

        
        public void delete(Book book) {
                Connection connection = null;
                try {
                        connection = dataSource.getConnection();
                        Statement statement = connection.createStatement();
                        int rowUpdated = statement.executeUpdate(
                                        String.format(
                                                "DELETE FROM book WHERE book_id = %s",
                                                book.getBookId()));
                        if (rowUpdated != 1) {
                                throw new IllegalStateException("Error when trying to delete " + book);
                        }
                        statement.close();
                } catch (SQLException e) {
                        throw new RuntimeException(e.getMessage(), e);
                } finally {
                        try {
                                connection.close();
                        } catch (SQLException e) {
                                throw new RuntimeException(e.getMessage(), e);
                        }
                }

        }

        private Book mapRow(ResultSet rs) throws SQLException {
                return new Book (
                        rs.getInt("book_id"),
                        rs.getString("title"),
                        rs.getString("author"),
                        rs.getInt("year"));
        }

}

With JPA we can achieve the same outcome with much less code. JPA API leverage annotation based entity mapping to make it more easier to map a POJO into database. Let’s decorate our Book entity with some annotation to tell JPA what our database schema looks like.


public class Book {
        @Id  private int bookId;
         private String title;
         private String author;
         private int year;

        public Book() {}

        public Book(int bookId, String title, String author, int year) {
                this.bookId = bookId;
                this.title = title;
                this.author = author;
                this.year = year;
        }

        // Getters and setters omitted for brevity
}

As you can see, we still have the same Book entity POJO class, and the extra , @Id and annotations is enough to tell JPA what the database schema looks like, and how to persist / retrieve the instance from database. Following is a sample of JPA implementation of BookDAO. Note how in this implementation we don’t have to write any native SQL to retrieve, or save the object, and more importantly, no cumbersome code to map the result set row into an entity object!

        /**
         * Simple implementation of BookDAO using JPA. Each method simply starts and closes
         * transaction. Entity object returned by these methods are always detached
         *
         *  gerry
         *
         */
        public class BookJPADAOImpl implements BookDAO {

                private EntityManager em;

                public BookJPADAOImpl (EntityManager entityManager) {
                        this.em = entityManager;
                }

                
                public Book findById(int bookId) {
                        Book result = em.find(Book.class, bookId);
                        em.detach(result);
                        return result;
                }

                
                public List list() {
                        List result = em.createQuery("SELECT b FROM Book b", Book.class)
                                        .getResultList();
                        for (Book b : result) { em.detach(b); }
                        return result;
                }

                
                public int save(Book book) {
                        em.getTransaction().begin();
                        em.persist(book);
                        em.getTransaction().commit();
                        em.detach(book);
                        return book.getBookId();
                }

                
                public void update(Book book) {
                        em.getTransaction().begin();
                        em.merge(book);
                        em.getTransaction().commit();
                        em.detach(book);
                }

                
                public void delete(Book book) {
                        em.remove(book);
                        em.flush();
                }

        }

This is only a very simple example of JPA, but  if you read more, it’s capable of much more such as mapping entity relations, and implementing optimistic locking using row versioning.

You can view or checkout the sample code here: . In the sample code I wrote few unit test classes using HyperSQL in memory database.

Following are good reference links if you want to find out about: