Friday, February 19, 2010

JSON RESTfull Service Using Jersey with Hibernate Persistence on Glassfish

Tips:
  • to setup Hibernate to use a datasource defined under Glassfish, see my other post.
  • usefull Jersey annotations:
    • for the resource class: @Path("/person/")
    • for a method: @GET @Path("{personId}/") @Produces("application/json"). Then, you can use public Person getUser(@PathParam("personId") int personId) for method declaration.
    • add @Consumes("application/json") with public Person post(Person person) method declaration. Jersey takes care of unmarshaling the Json into Person object.
  • to return an error code from the restfull webservice, throw a new WebApplicationException(Response.Status.NOT_FOUND), for example. This one would return 404 error. No Need to declare the jersey handler method as "throws ...".
  • to unit test the service, use com.sun.jersey.api.client.Client:
    Person result = Client.create().resource("http://localhost:8080/myapp/person")
       .type("application/json")
       .post(Person.class,new Person("Jon Smith",133));
    Assert.assertEquals("Jon Smith", result.getName()); 
  • To pass an object retrieved via Hibernate as a response from a webservice, it needs to be serializable. But objects retrieved this way have additional members and so they need to be converted to a pure entity object (Person, in my case). I have used the Dozer library for this purpose (see the code below).
  • The entity classes (Person and PersonCollection, in my example)need to be annotated with @XmlRootElement.

Code:
Complete web service implementation class code (in RESTfull, call a resource):
package olcc.jersey.service;

import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import olcc.entity.HibernateUtil;
import olcc.entity.Person;
import olcc.entity.PersonCollection;
import org.dozer.DozerBeanMapper;
import org.dozer.Mapper;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;

@Path("/person/")
public class PersonResource {
 
 @GET @Path("{personId}/") @Produces("application/json")
 public Person getPerson(@PathParam("personId") int personId) {
  Session session = HibernateUtil.getSessionFactory().getCurrentSession();
  Transaction tx = null;
  Person personClean;
  
  try{
   tx = session.beginTransaction();
   Person person = (Person) session.load(Person.class,personId);
   
   Mapper mapper = new DozerBeanMapper();
   personClean = mapper.map(person,Person.class);

   session.getTransaction().commit();

  } catch( Exception ex) {
   if( tx != null ) tx.rollback();
         throw new WebApplicationException(Response.Status.NOT_FOUND);
  }
  return personClean;
 }
 
 @GET @Produces("application/json")
 public PersonCollection get() {
  Session session = HibernateUtil.getSessionFactory().getCurrentSession();
    session.beginTransaction();
  List<person> result = session.createQuery("from Person").list();

  Mapper mapper = new DozerBeanMapper();
  PersonCollection persons = new PersonCollection();
        
  for( Person person : result ) {
    persons.add(mapper.map(person,Person.class));
  }
  session.getTransaction().commit();
        
  return persons;
 }
 
 @POST @Consumes("application/json")
 @Produces("application/json")
 public Person post(Person person) {
  Session session = HibernateUtil.getSessionFactory().getCurrentSession();
  session.beginTransaction();
  
  session.save(person);
  
  session.getTransaction().commit();
  return person;
 }

 @GET @Path("delete/{personId}/") @Produces("application/json")
 public Person deleteOne(@PathParam("personId") int personId) {
  Session session = HibernateUtil.getSessionFactory().getCurrentSession();
  session.beginTransaction();
  Transaction tx = null;
        Person personClean;
  
  try{
   tx = session.beginTransaction();
   Person person = (Person) session.load(Person.class,personId);
   session.delete(person);
   
   Mapper mapper = new DozerBeanMapper();
   personClean = mapper.map(person,Person.class);

   session.getTransaction().commit();

  } catch( Exception ex) {
   if( tx != null ) tx.rollback();
         throw new WebApplicationException(Response.Status.NOT_FOUND);
  }

  return personClean;
 }
}

Open Questions:
  • I'm not sure where the Hibernate session should be closed. I don't think this can be done at the end of each handler method.
  • How to use JTA for transaction management instead of direct JDBC transaction management?
  • Most of the Hibernate-specific code should go into a DAO, with most of it into a generic DAO. But the recommended by Hibernate documentation generic DAO is defined in terms of state-oriented data access API (makePersistent() and makeTransient() methods), which are less intuitive for me. What is the advantage of using them and how to use them from CRUD operations?

Wednesday, February 17, 2010

Configure Hibernate to Use A Datasource

I'm using Glassfish application server, on which (using its Console) I have created a JDBC datasource (JDBC Resource). I'd like configure the hibernate framework to use it. The resons:
  • Connection pooling (it's true that I could use the Hibernate's own connection pooling)
  • Portability: moving the application to another application server is easy, as long as they both provide a datasource with the same name (Hibernate dialect may still need to be changed appropriately).
hibernate.cfg.xml File
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
  "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory name="hibernate/sessionFactory">
        <property name="connection.datasource">jdbc/derbydb</property>
        <property name="dialect">org.hibernate.dialect.DerbyDialect</property>
        <property name="current_session_context_class">thread</property>
        <property name="hbm2ddl.auto">create</property>
    
     <mapping resource="olcc/entity/Person.hbm.xml"/>
    </session-factory>
</hibernate-configuration>


HibernateUtil.java File
private static SessionFactory buildSessionFactory() {
    return new Configuration().configure().buildSessionFactory();
}


The Application Code
Session session = HibernateUtil.getSessionFactory().getCurrentSession();

Thursday, February 11, 2010

Using Powermock to Mock Java Objects for Unit Testing

This test uses the EasyMock style (as opposed to Mockito style), so it needed the corresponding file download. The code sample (click on view source icon to see it better):
import org.junit.Test;
import org.junit.runner.RunWith;

import static org.easymock.EasyMock.expect;
import static org.powermock.api.easymock.PowerMock.*;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.legacy.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest({Person.class })
public class PersonResourceTest {

    @Test
     public void testPost() {

        Person personMock = createMock(Person.class);
        expect(personMock.getName()).andReturn("Jon Smith");
        replay(personMock);

    // do the test...        

        Assert.assertEquals("Jon Smith", result.name);
    }
    
}

Wednesday, February 10, 2010

SQL Checks And Rules

In most data models, there are columns that should take values only from a limited set.  For example, a state of License (as in our current project) may only take three values: AppliedFor, Granted or Denied. This kind of restriction is part of what is called Domain Level Integrity. How do you implement it?

Old Way: Separate Table
I used to create a separate table for the allowed values. It can be done, but this table has only couple records in it, is rarely updated and using a whole table for this is almost an overkill. Also, you end up writing more code to manipulate it.

New Way: SQL Rules
There is an SQL construct purpose of which is exactly this kind of constraint: SQL Rule (for Sybase docs: see this). An example:

create rule pub_idrule 
as @pub_id in ("1389", "0736", "0877", "1622", "1756")
or @pub_id like "99[0-9][0-9]" 
 

Wednesday, February 3, 2010

Persistence Frameworks, ORMs

The big three, I consider mainstream (from Java perspective):
  • Hibernate
  • JPA
  • JDO
 I have sorted them in the market share order, but there are some interesting facts that make all three important:
  • Hibernate is definitely the strongest, most popular ORM framework for Java and .Net, but it's not a standard per se.
  • JPA is a standard and it's fully supported by HIbernate, so choosing it gives you some advantages over Hibernate. Its design was based on Hibernate and JDO.
  • You can use Hibernate and restrict yourself to the JPA-only, which gives you a portability to another JPA-type framework, if you so choose in future.
  • JDO, although the oldest one, is the preferred persistence mechanism for Google Application Engine, the Java application hosting service of Google (although, you can also use JPA with it).
Which framework to choose? Your choice.  Need more help choosing? Try this article.

Saturday, January 2, 2010

Trends in Web Application Development

Recently, I have been exploring the landscape of web application development a little but.  Here are some of the results. Comments are welcome. What is the real trend?

Overall Look
Simple. I have used indeed.com trends tool to compare number of jobs openings for major web application development platforms and technologies. Result is below:

Some conclusions that seem obvious:
  • Major development platforms had a hit in mid-2008, but recently are slowing down. Note, that the latter can't be explained with economy, since the graph shows the percentage of job postings, not the absolute numbers. Possibly, hiring in IT slowed down as compaed to other areas, though.
  • Definitely, the Web2.0 (RIA) technologies are experiencing the strongest, or better to say the only growth. Look at Ajax. More analysis on this below.
Now, to verify this result, let's see the results from google.com/trends.

Server-Side Technologies
This comes from google.com/trends:
Server-Side Technologies

One technology, I have definitely missed on the indeed.com side, it seems, is the PHP. A strong player.

Client-Side Technologies
Client-Side Technologies

The most surprising conclusion from the graph above is that Flash technology is so much above all of the rest. And it's significantly more obvious than on the job openings analysis. That may mean, that Flash is coming to the market as a strong candidate. However, since flash is not necessarily used for application development, I am adding another graph, with flex web instead of flash.
RIA (Web2.0) Technologies

Here. it seems we can see the currently strongest players. Ajax, which, unfortunately is split among many libraries, is still the front runner. However, it seems to give in to Flex and Silverlight. That wouldn't be a big surprise, since Ajax based on JavaScript is a rather low-level development hack, only somewhat improved by using an Ajax framework.
Finally, one more graph. It comes from indeed.com. A comparison of job openings for Flex, Silverlight and GWT developer jobs:

And, just for a comparison, a sample of mobile development job trends:




Conclusion
So, that's it for my analysis. What do you think? What is the future of web application development? Specifically:
  • What should application developers invest in for the the 2010?
  • What will in be over the next five years (futuristic prediction)?
Waiting for your comments.

Thursday, December 24, 2009

Mocking Objects To Unit Test Android OS Applications

First Things First
Testing applications for Android OS can be done in two ways:
  • test on the Android platform using android.test and android.test.mock classes, or
  • testing on the development machine using the regular Java VM and standard Java unit testing and object mocking frameworks.
The good discussion as to pros and cons of each is presented in this article by a Google developer (although not an Android developer). The conclusion was to use the second option, due to valid limitations ofTo the first approach.

Mocking

What are mock objects? They are fake objects that can pretend to the callers to be an object they pretend to be, but are under full control of the test. Full control means two things here:
  • The test can monitor what methods of a mock object are called during the test and what parameters are provided, and
  • The test can dictate what results a mock class should return, without having to actually use, or even implement the class that is mocked.
Why mock objects? Without mocking objects, unit testing is limited to cases where the class under test doesn't use any other classes, or may be just some basic classes. The fuller answer is to why, can be given the following answers. To simplify explaining these answers, let's assume that we want to test class A which uses class B:
  • If some of the class A results depend on class B results. Without using mocking, the test would include the testing of class B. Often, we want to be able to write a test that tests just a single class. Smaller tests can be less brittle, that is they don't break as often with the changes done to the code after the test has been written.
  • If using class B in the test environment is not practical. For example, if the class B is a database, a web service or a GPS module, both of which are tightly coupled to the real world.
  • If we want to test class A before class B is implemented, so it doesn't exists, yet.
  • In general, mocking allows us to test not only an internal code of class A, but also if it uses class B correctly. So, it tests the class collaboration.
For more info on this topic see wikipedia article or this.

What Tools Are Available for Mocking?
The least of tools is quite long. In last couple years, I used probably the following ones:
  • JMock
  • Easy Mock
  • Mockito
  • PowerMock
The reasons I moved from one framework to another are new features (PowerMock can mock even static and final methods) and simpler syntax/tests (esp. Mockito). Also, PowerMock is in a way a conglomerate of Mockito and EasyMock. Although, that means that sometimes, when you use PowerMock you have to use the Mockito, and sometimes the EasyMock like API's. The good part is, that onces you know what mocking is about, using different API's is not that different.