Thursday, September 24, 2009

Sorting Collections in Java

Now this is a pretty basic requirement that Java developers often face. You may want to sort an array of Strings or an List of Complex user defined object based on any field of that object. Java provides you with several options for this purpose that we are going to explore.

Sorting An Array of Pre-defined Data Types

To sort simple objects like String, Integer or primitive Data types, you can simply use build-in functions like:

  • Collections.sort( );
  • Arrays.sort( );

Sorting List of Objects – Comparable Vs Comparator

A more practical example would be to sort a User-defined Object on any field of that Object. Suppose we have a Person class that looks like the following:

Personjava

Now, we want to sort an ArrayList of Persons based on their name, we have 2 options:

Have Person Class Implement Comparable Interface

Have your person class implement the Comparable Interface, which makes you implement compareTo(..) method, which is actually used by build-in sorting methods to sort Persons. This method looks like following and compares two person objects, which determines which Person should come first in the sorted order.

PersonComparable

This method compareTo(..) is used to Compare two Person Objects based on their name. It returns an integer value: 0 if both of them are equal, positive value if the first object comes before the second one, and negative value if first object comes after the second one.

Now call sort() on it as follows,

sortingPersons

where persons is an ArrayList of Persons. As already said, the sort() method internally uses compareTo(..) method to sort these Person Objects

Create a Separate Class (Comparator Class) implementing Comparator Interface

A better way to sort these Persons is to create a separate comparator class as shown below.

comparatorPerson

Here we have created a static inner class which is used in sort() method as follows:

personComparator

Comparable Vs Comparator

I call it a better way as you can now sort your Person class on different fields: Suppose now you want to sort Persons based on their Age, then all you need to do is create a new Comparator class based on age and call sort method with this comparator.

Note:

The code shown above is compatible with Java 1.5 and above. The non-generic functions for Comparable and Comparators looks a bit different but inherently serve the same purpose.

Saturday, September 5, 2009

Hibernate Basic Tutorial

This blog post is meant for beginners who want to start with Hibernate and could not find an easy way to set up the basic project. Pre-requisites for understanding this are basic knowledge of Core Java and JDBC knowledge.

Introduction to Hibernate

Hibernate is basically an Object-Relational Mapping tool that is used to query against the database in an effective manner and can convert the results into (Java) objects pretty easily.

In simple terms, one can say that you can Map one database table to a Java class and objects of that class will correspond to rows in that database table. (Obviously, complex mappings also exists and we can specify all kind of relationships but to begin with, we will talk about the easy ones).

You can think of Hibernate as a Wrapper over JDBC. The reason I choose the word ‘Wrapper’ is to emphasize on the fact that Hibernate itself uses JDBC under the hood. So, its not really a radically different technology that we are going to learn.

Some Advantages of Hibernate

  1. Database Independence – The code that you write is not dependent on the underlying database. It is also known as transparent persistence as you can always change the underlying database without changing any of your Java code, the only change required is in a Hibernate configuration file. This also means independence from the queries that you will otherwise write specific to a database.
  2. Open Source – Hibernate is Free and Open Source and licensed under LGPL (Less GNU Public License)
  3. Performance – It claims to have improved performance when compared to JDBC API.
  4. Enhanced API - It also provides an enhanced Criteria API to query against the database in an effective fashion. Apart from Criteria API, one can also use Native SQL or HQL (Hibernate Query Language)

Lets Get Started

So lets start with setting up a basic Hibernate Project in Eclipse. Software and Other stuff that you require are

Open Eclipse IDE. Create a new Java Project. Name it as you like and press finish. Before we start coding, first let us add the required libraries:

Hibernate JARs (from Hibernate Core Framework). Consists of classes like Session, Transaction, Criteria etc. which are used to write Hibernate code.

  • hibernate3.jar
  • common-collections-3.1.jar
  • javassist-3.4.GA.jar
  • jta-1.1.jar
  • dom4j-1.6.1.jar
  • antlr-2.7.6.jar

Logging JARs (used to log the queries fired and for other purposes)

  • log4j-1.2.13.jar
  • slf4j-api-1.5.8.jar
  • slf4j-log4j12-1.5.8.jar

Data-Base specific Driver JAR (which contains the implementation of JDBC specification and is used to connect to underlying DB )

  • mysql-connector-java-5.1.7-bin.jar

After adding the required libraries, let us create a table in our database, which we will use in our example. Following syntax is used for MySQL to create a student table in ‘hibernate’ schema :

studentsql

As already discussed, Hibernate Provides us with the Capability of Mapping a Table in a Relational Database to a Java Class. So Any Operations that you perform the objects of that class are actually performed on the rows of that database table when you save these objects using Hibernate API.

So, lets create a Student Class in Eclipse (Student.java). This class will have (in this simple case) the instance variables with one-to-one correspondence with the columns of the Student Table that we created above. These classes generally follow JavaBeans Pattern by having Getters and Setters for every property and an empty constructor. So, this is how our Student.java looks like:

Studentpic

Mapping Java Class to Database Table

Now, we must provide the mapping so that Hibernate can actually map this java file against our table. This mapping is provided in a XML file, which we name as Student.hbm.xml. Although you can provide any name, but keeping the same name as that of the class helps in identification if required later on. The *.hbm.xml extension is mandatory for all mapping files. The Mapping File looks like:

Studenthbm

Let us spend a few minutes pondering over this mapping file. Although, most of it is pretty straight-forward. It says that we are mapping our class Student (Student.java) to table Student with primary key as id which maps to id column of table. The generator tag is used to generate primary keys. Different types of generator classes can be used for this purpose. Most commonly used are native (which means use database dependent scheme for generating primary keys), increment (which can be used to increment normal data types like Long, Integer etc.

Other tags in the file simply maps properties of Java Class to Database columns. You can also specify data types of these properties. Hibernate supports almost all data types that Java offers. This is perhaps the simplest Mapping file that you will see and use. More complex mappings are normally used but we stick to basics since there is much more to learn.

Hibernate Configuration

Are we missing something ? So far we have created a Database table, a Java file and a XML file that specifies the mapping used by Hibernate, but so far we have not told Hibernate anything about the location of database, the username-password to access it, the name of schema in which all these database objects lie. So to specify these, we use Hibernate Configuration File hibernate.cfg.xml which looks like the following:

hibernatecfgxml

There are many ways to provide this configuration to Hibernate. One of them is to use this file.

  • The property connection.url tells the location of the schema (named as hibernate) to which we connect using Hibernate. It contains all the database objects that we use in our Hibernate application.
  • The connection.username and connection.password properties specifies the username and password to connect to our schema.
  • This file also specifies all the hbm.xml mapping files that we created (only one in this case) as mapping resources. Yes, this is not a best practice and better techniques do exist.
  • The property hibernate.show_sql property is used to generate all SQL statements that Hibernate internally uses.
  • There are many other properties as well which we have skipped

Logging APIs

Hibernate uses log4j and slf4j for logging purposes. We use log4j.properties to specify logging properties.

log4properties

Finally, lets write some Code

I have always experienced that setting up environment for any web application is far more difficult than actually writing the code. ;) So, perhaps the difficult part of setting up the environment for our Hibernate Application ( a one-time activity ) is over, and we can write Hibernate code to insert and retrieve data.

Again, there are many best practices to code like using Connection Pooling for connections, Transaction Management in an effective manner. But for demo purposes, we have ignored all of it as the purpose here to get started with Hibernate.

Hibernate Session Factory

We create a Session Factory which is then used to get new Hibernate sessions, close sessions and retrieve existing sessions.

hibernatesessionfactory

Now we create a Test Java file (TestHibernate.java) that creates a new Student, retrieves all existing Students, delete a particular student.

Creating a New Student

createStudent

Retrieving all Students

getAllStudents

Delete A Student

deleteStudent

Project Structure

Now that we have created all the files that we need, we really missed the big part. How to organize them ?? So lets see how we should organize all these files we have created so far.

projectStructure

The TestHibernate.java class contains all the hibernate methods shown above plus a main method (for demo) to test these methods. When you run this Java file, check out the messages printed on the console.

I hope I have told all the implementation details in the best possible ways I can. I hope you will have a good time building applications with Hibernate. :-)

Notes

I faced a few problems in setting up project. Mostly were related to missing JARs or usage of old JARs, but few minutes of googling really helped. That’s why I have clearly stated the JARs that I used.

Connection Pooling with Hibernate is done using C3P0 connection pooling mechanism.

Last but not the least, this is just a small yet decent beginning in the huge world of Hibernate. In case you find any mistake, please leave it as a comment. Any suggestions and comments are welcome. :-)