July 21, 2011

EJB 3.1 Cookbook by Richard Reese review

Recently I received a copy of EJB 3.1 Cookbook (courtesy to Packt Publishing) with a kind request to prepare a review. And since I have just got my new Kindle reader, this was a great opportunity to test them together.


EJB 3.1 Cookbook by Richard Reese aims to provide “a collection of simple but incredibly effective recipes” – quoting the subtitle. The book covers expected part of the EJB stack: session and message-driven beans, JPA, security, interceptors, timer service and web services. Contents are
organized around so called recipes – short (no more than three pages long) micro-chapters focused on one specific issue. This is the most advantageous feature of this publication: all recipes all self-contained most of the time, so one can jump between them and apply the most suitable in given scenario. This makes the book suitable for both the beginners, which should read it from cover to cover and slightly more experienced developers. However the latter ones will probably prefer more comprehensive sources and skip significant parts of the book.

Although I found the book structure very convenient, contents (both granularity and volume) are highly subjective and controversial. On the one hand the author devotes five recipes to describe separately each JMS message type (string, byte, stream, map and object) – each one is almost identical. Whilst he could only list different types, he fills half of the JMS chapter this way (sic!) On the other hand, there is only one recipe explaining new JPA 2.0 Criteria API – to make matters worse, only using weakly typed queries. Probably one of the most important new features in EJB 3.1 stack has been covered on two pages. And this API is not particularly easy to grasp. To depict you the scale – the art of adding Bean Validation annotations (@NotNull etc.) on fields required ten pages and eight recipes... Where a half-page bullet-list would suffice.

The last chapter – EJB Techniques – is very intriguing. Lots of valuable and accurate tips have been given, like the difference between Date and Calendar, logging and dealing with exceptions, effective String manipulations. Despite appearances, this is not the basic Java knowledge and many experienced programmers still don't know that SimpleDateFormat is not thread-safe and that Date class does not store time zone. I am really happy that this kind of knowledge found its way in the book. Unfortunately – in the wrong one. That being said, there are more appropriate books, not focused on EJB or even Java EE. Here it just looks like putting anything useful to reach dozen chapters in total.

July 3, 2011

Poor man's CRUD: jqGrid, REST, AJAX, and Spring MVC in one house

More than two years back I wrote an article on how two implement elegant CRUD in Struts2. Actually I had to devote two articles on that subject because the topic was so broad. Today I have taken much more lightweight and modern approach with a set of popular and well established frameworks and libraries. Namely, we will use Spring MVC on the back-end to provide REST interface to our resources, fabulous jqGrid plugin for jQuery to render tabular grids (and much more!) and we will wire up everything with a pinch of JavaScript and AJAX.

Back-end is actually the least interesting part of this showcase, it could have been implemented using any server-side technology capable of handling RESTful requests, probably JAX-RS should now be considered standard in this field. I have chosen Spring MVC without any good reason, but it's also not a bad choice for this task. We will expose CRUD operations over REST interface; the list of best selling books in history will be our domain model (can you guess who is on the podium?)

@Controller
@RequestMapping(value = "/book")
public class BookController {

  private final Map<Integer, Book> books = new ConcurrentSkipListMap<Integer, Book>();

  @RequestMapping(value = "/{id}", method = GET)
  public @ResponseBody Book read(@PathVariable("id") int id) {
    return books.get(id);
  }

  @RequestMapping(method = GET)
  public @ResponseBody Page<Book> listBooks(
      @RequestParam(value = "page", required = false, defaultValue = "1") int page,
      @RequestParam(value = "max", required = false, defaultValue = "20") int max) {
    final ArrayList<Book> booksList = new ArrayList<Book>(books.values());
    final int startIdx = (page - 1) * max;
    final int endIdx = Math.min(startIdx + max, books.size());
    return new Page<Book>(booksList.subList(startIdx, endIdx), page, max, books.size());
  }
}

Few things need explanation. First of all for the purposes of this simple showcase I haven't used any database, all the books are stored in an in-memory map inside a controller. Forgive me. Second issue is more subtle. Since there seems to be no agreement on how to handle paging with RESTful web services, I used simple query parameters. You may find it ugly, but I find abusing Accept-Ranges and Range headers together with 206 HTTP response code even uglier.

Last notable detail is the Page<Book> wrapper class: