Wednesday, September 12, 2007

Interface vs. abstract class

Choosing interfaces and abstract classes is not an either/or proposition. If you need to change your design, make it an interface. However, you may have abstract classes that provide some default behavior. Abstract classes are excellent candidates inside of application frameworks.

Abstract classes let you define some behaviors; they force your subclasses to provide others. For example, if you have an application framework, an abstract class may provide default services such as event and message handling. Those services allow your application to plug in to your application framework. However, there is some application-specific functionality that only your application can perform. Such functionality might include startup and shutdown tasks, which are often application-dependent. So instead of trying to define that behavior itself, the abstract base class can declare abstract shutdown and startup methods. The base class knows that it needs those methods, but an abstract class lets your class admit that it doesn't know how to perform those actions; it only knows that it must initiate the actions. When it is time to start up, the abstract class can call the startup method. When the base class calls this method, Java calls the method defined by the child class.

Many developers forget that a class that defines an abstract method can call that method as well. Abstract classes are an excellent way to create planned inheritance hierarchies. They're also a good choice for nonleaf classes in class hierarchies.

Q: Why use interfaces to develop Java applications?
A: It is advisable to design relatively large applications using interfaces because it makes the whole system easier to modify, extend and integrate new features. To start with, you may only have one implementation of a given interface, but if you find you need slightly different behaviour in special circumstances, you only need write a class that conforms to one of the existing interfaces and it will drop in place without major modifications.

Interfaces also allow you to adapt a class from a different hierarchy to work in an existing application. The class only needs to declare it implements the interface, provide the necessary methods and it can be integrated directly as if it were created for the job.

Q: What is the difference between abstract classes and interfaces?
A: A Java interface is a definition of a class type without any concrete implementation. Typically, an interface consists of one or more method signatures that a subclass must fulfil to conform to the type. In effect, all their methods are abstract, and interfaces cannot be instantiated

Q: Do interfaces have member variables?
A: Interfaces may have member variables, but these are implicitly final and static because they are not inherited by extension. In effect interface variables are constants that are available to all implementations and may be used as key references for method arguments for example.

Q: Can we create an object for an interface?
A: Yes, it is always necessary to create an object implementation for an interface. Interfaces cannot be instantiated in their own right, so you must write a class that implements the interface and fulfil all the methods defined in it.

public class Concrete implements ExampleInterface {

...
}
Q: What is a marker interface?
A: Marker interfaces are those which do not declare any required methods, but signify their compatibility with certain operations. The java.io.Serializable interface is a typical marker interface. It does not contain any methods, but classes must implement this interface in order to be serialized and de-serialized.

Q: Should I use a public access modifier for interface methods?
A: Java interfaces are used to define a public Application Programming Interface (API) for classes to implement, so a public modifier is redundant in this context. Non-public modifiers are not valid for interfaces, so the compiler should fail and warn you in this case.

Interface usage
Q: What are the rules for passing subclasses for method arguments?
A: It may help to discuss an example using birds: an interface called Avian, a superclass FlyingBird that implements Avian and two concrete classes: Parrot and Penguin. Parrot extends FlyingBird, so is implicitly an Avian type, but Penguin does not, it only implements Avian. The examples below work through all possibilities, passing references to methods soundBirdCall(FlyingBird) and displayPlumage(Avian)

Q: When should I use abstract classes rather than interfaces?
A: Abstract classes are are often used to provide methods that will be common to a range of similar subclasses, to avoid duplicating the same code in each case. Each subclass adds its own features on top of the common abstract methods.

Q: Can an interface be declared final?
A: It is not permitted to declare an interface as final, it will cause a compilation error. It does not make sense to declare an interface final because it contains no implementation code and cannot instantiated in its own right. The final modifier is used to prevent the extension of concrete classes.

Q: This code seems to be instantiating an interface!
A: The code you are looking at declares an inline anonymous class that implements an interface, which has a similar effect. This declaration does not instantiate the interface, but defines the type of the anonymous class, which has no name of its own. This approach is often used in AWT or Swing applications where a class is required to fulfil a minimal interface and it is not necessary to retain a reference to it by assignment.

Ocerriding vs Hiding

Can I override a static method?
Many people have heard that you can't override a static method. This is true - you can't. However it is possible to write code like this:

class Foo {
public static void method() {
System.out.println("in Foo");
}
}
//commited by sanjay
class Bar extends Foo {
public static void method() {
System.out.println("in Bar");
}
}
This compiles and runs just fine. Isn't it an example of a static method overriding another static method? The answer is no - it's an example of a static method hiding another static method. If you try to override a static method, the compiler doesn't actually stop you - it just doesn't do what you think it does.
So what's the difference?

Briefly, when you override a method, you still get the benefits of run-time polymorphism, and when you hide, you don't. So what does that mean? Take a look at this code:

class Foo {
public static void classMethod() {
System.out.println("classMethod() in Foo");
}

public void instanceMethod() {
System.out.println("instanceMethod() in Foo");
}
}

class Bar extends Foo {
public static void classMethod() {
System.out.println("classMethod() in Bar");
}

public void instanceMethod() {
System.out.println("instanceMethod() in Bar");
}
}

class Test {
public static void main(String[] args) {
Foo f = new Bar();
f.instanceMethod();
f.classMethod();
}
}
If you run this, the output is
instanceMethod() in Bar
classMethod() in Foo
Why do we get instanceMethod from Bar, but classMethod() from Foo? Aren't we using the same instance f to access both of these? Yes we are - but since one is overriding and the other is hiding, we see different behavior.
Since instanceMethod() is (drum roll please...) an instance method, in which Bar overrides the method from Foo, at run time the JVM uses the actual class of the instance f to determine which method to run. Although f was declared as a Foo, the actual instance we created was a new Bar(). So at runtime, the JVM finds that f is a Bar instance, and so it calls instanceMethod() in Bar rather than the one in Foo. That's how Java normally works for instance methods.

With classMethod() though. since (ahem) it's a class method, the compiler and JVM don't expect to need an actual instance to invoke the method. And even if you provide one (which we did: the instance referred to by f) the JVM will never look at it. The compiler will only look at the declared type of the reference, and use that declared type to determine, at compile time, which method to call. Since f is declared as type Foo, the compiler looks at f.classMethod() and decides it means Foo.classMethod. It doesn't matter that the instance reffered to by f is actually a Bar - for static methods, the compiler only uses the declared type of the reference. That's what we mean when we say a static method does not have run-time polymorphism.

Because instance methods and class methods have this important difference in behavior, we use different terms - "overriding" for instance methods and "hiding" for class methods - to distinguish between the two cases. And when we say you can't override a static method, what that means is that even if you write code that looks like it's overriding a static method (like the first Foo and Bar at the top of this page) - it won't behave like an overridden method.

So what about accessing a static method using an instance?

It's possible in Java to write something like:

f.classMethod();
] where f is an instance of some class, and classMethod() is a class method (i.e. a static method) of that class. This is legal, but it's a bad idea because it creates confusion. The actual instance f is not really important here. Only the decleared type of f matters. That is, what class is f declared to be? Since classMethod() is static, the class of f (as determined by the compiler at compile time) is all we need.
Rather than writing:

f.classMethod();
It would be better coding style to write either:
Foo.classMethod();
or
Bar.classMethod();
That way, it is crystal clear which class method you would like to call. It is also clear that the method you are calling is indeed a class method.
Barring that, you could always come up with this monstrosity:

f.getClass().getMethod("classMethod", new Class[]).invoke(f, new Object[]);
But all this could be avoided by simply not trying to override your static (class) methods. :-)

Tuesday, September 11, 2007

Java Virtual Machine

What is the Java Virtual Machine? Why is it here?
The Java Virtual Machine, or JVM, is an abstract computer that runs compiled Java programs. The JVM is "virtual" because it is generally implemented in software on top of a "real" hardware platform and operating system. All Java programs are compiled for the JVM. Therefore, the JVM must be implemented on a particular platform before compiled Java programs will run on that platform.




The JVM plays a central role in making Java portable. It provides a layer of abstraction between the compiled Java program and the underlying hardware platform and operating system. The JVM is central to Java's portability because compiled Java programs run on the JVM, independent of whatever may be underneath a particular JVM implementation.


What makes the JVM lean and mean? The JVM is lean because it is small when implemented in software. It was designed to be small so that it can fit in as many places as possible -- places like TV sets, cell phones, and personal computers. The JVM is mean because it of its ambition. "Ubiquity!" is its battle cry. It wants to be everywhere, and its success is indicated by the extent to which programs written in Java will run everywhere.


Java bytecodes

Java programs are compiled into a form called Java bytecodes. The JVM executes Java bytecodes, so Java bytecodes can be thought of as the machine language of the JVM. The Java compiler reads Java language source (.java) files, translates the source into Java bytecodes, and places the bytecodes into class (.class) files. The compiler generates one class file per class in the source.


To the JVM, a stream of bytecodes is a sequence of instructions. Each instruction consists of a one-byte opcode and zero or more operands. The opcode tells the JVM what action to take. If the JVM requires more information to perform the action than just the opcode, the required information immediately follows the opcode as operands.


A mnemonic is defined for each bytecode instruction. The mnemonics can be thought of as an assembly language for the JVM.

Java bytecode:

This article gives you an understanding of Java bytecode that will enable you to be a better programmer. Like a C or C++ compiler translates source code into assembler code, Java compilers translate Java source code into bytecode. Java programmers should take the time to understand what the bytecode is, how it works, and most importantly, what bytecode is being generated by the Java compiler.

Why understand bytecode?

Bytecode is the intermediate representation of Java programs just as assembler is the intermediate representation of C or C++ programs. The most knowlegable C and C++ programmers know the assembler instruction set of the processor for which they are compiling. This knowledge is crucial when debugging and doing performance and memory usage tuning. Knowing the assembler instructions that are generated by the compiler for the source code you write, helps you know how you might code differently to achieve memory or performance goals. In addition, when tracking down a problem, it is often useful to use a debugger to disassemble the source code and step through the assembler code that is executing.

An often overlooked aspect of Java is the bytecode that is generated by the javac compiler. Understanding bytecode and what bytecode is likely to be generated by a Java compiler helps the Java programmer in the same way that knowledge of assembler helps the C or C++ programmer.

The bytecode is your program. Regardless of a JIT or Hotspot runtime, the bytecode is an important part of the size and execution speed of your code. Consider that the more bytecode you have, the bigger the .class file is and the more code that has to be compiled by a JIT or Hotspot runtime. The remainder of this article gives you an in depth look at Java bytecode.

Generating bytecode

javac Employee.java
javap -c Employee > Employee.bc


Compiled from Employee.java
class Employee extends java.lang.Object {
public Employee(java.lang.String,int);
public java.lang.String employeeName();
public int employeeNumber();
}

Method Employee(java.lang.String,int)
0 aload_0
1 invokespecial #3
4 aload_0
5 aload_1
6 putfield #5
9 aload_0
10 iload_2
11 putfield #4
14 aload_0
15 aload_1
16 iload_2
17 invokespecial #6
20 return

Method java.lang.String employeeName()
0 aload_0
1 getfield #5
4 areturn

Method int employeeNumber()
0 aload_0
1 getfield #4
4 ireturn

Method void storeData(java.lang.String, int)
0 return



This class is very simple. It contains two instance variables, a constructor and three methods. The first five lines of the bytecode file list the file name that is used to generate this code, the class definition, its inheritance (by default, all classes inherit from java.lang.Object ), and its constructors and methods. Next, the bytecode for each of the constructors is listed. Then, each method is listed in alphabetical order with its associated bytecode.

You might notice on closer inspection of the bytecode that certain opcodes are prefixed with an `a' or an `i'. For example, in the Employee class constructor you see aload_0 and iload_2. The prefix is representative of the type that the opcode is working with. The prefix `a' means that the opcode is manipulating an object reference. The prefix `i' means the opcode is manipulating an integer. Other opcodes use `b' for byte, `c' for char, `d' for double, etc. This prefix gives you immediate knowledge about what type of data is being manipulated.

The details

To understand the details of the bytecode, we need to discuss how a Java Virtual Machine (JVM) works regarding the execution of the bytecode. A JVM is a stack-based machine. Each thread has a JVM stack which stores frames. A frame is created each time a method is invoked, and consists of an operand stack, an array of local variables, and a reference to the runtime constant pool of the class of the current method. Conceptually, it might look like this:



The array of local variables, also called the local variable table, contains the parameters of the method and is also used to hold the values of the local variables. The parameters are stored first, beginning at index 0. If the frame is for a constructor or an instance method, the reference is stored at location 0. Then location 1 contains the first formal parameter, location 2 the second, and so on. For a static method, the first formal method parameter is stored in location 0, the second in location 1, and so on.

The size of the array of local variables is determined at compile time and is dependent on the number and size of local variables and formal method parameters. The operand stack is a LIFO stack used to push and pop values. Its size is also determined at compile time. Certain opcode instructions push values onto the operand stack; others take operands from the stack, manipulate them, and push the result. The operand stack is also used to receive return values from methods.

public String employeeName()
{
return name;
}

Method java.lang.String employeeName()
0 aload_0
1 getfield #5
4 areturn



The bytecode for this method consists of three opcode instructions. The first opcode, aload_0, pushes the value from index 0 of the local variable table onto the operand stack. Earlier, it was mentioned that the local variable table is used to pass parameters to methods. The this reference is always stored at location 0 of the local variable table for constructors and instance methods. The this reference must be pushed because the method is accessing the instance data, name, of the class.

The next opcode instruction, getfield, is used to fetch a field from an object. When this opcode is executed, the top value from the stack, this, is popped. Then the #5 is used to build an index into the runtime constant pool of the class where the reference to name is stored. When this reference is fetched, it is pushed onto the operand stack.

The last instruction, areturn, returns a reference from a method. More specifically, the execution of areturn causes the top value on the operand stack, the reference to name, to be popped and pushed onto the operand stack of the calling method.

The employeeName method is fairly simple. Before looking at a more complex example, we need to examine the values to the left of each opcode. In the employeeName method's bytecode, these values are 0, 1, and 4. Each method has a corresponding bytecode array. These values correspond to the index into the array where each opcode and its arguments are stored. You might wonder why the values are not sequential. Since bytecode got its name because each instruction occupies one byte, why are the indexes not 0, 1, and 2? The reason is some of the opcodes have parameters that take up space in the bytecode array. For example, the aload_0 instruction has no parameters and naturally occupies one byte in the bytecode array. Therefore, the next opcode, getfield, is in location 1. However, areturn is in location 4. This is because the getfield opcode and its parameters occupy location 1, 2, and 3. Location 1 is used for the getfield opcode, location 2 and 3 are used to hold its parameters. These parameters are used to construct an index into the runtime constant pool for the class to where the value is stored. The following diagram shows what the bytecode array looks like for the employeeName method:



Actually, the bytecode array contains bytes that represent the instructions. Looking at a .class file with a hex editor, you would see the following values in the bytecode array:



2A , B4 , and B0 correspond to aload_0, getfield, and areturn, respectively.

public Employee(String strName, int num)
{
name = strName;
idNumber = num;
storeData(strName, num);
}

Method Employee(java.lang.String,int)
0 aload_0
1 invokespecial #3
4 aload_0
5 aload_1
6 putfield #5
9 aload_0
10 iload_2
11 putfield #4
14 aload_0
15 aload_1
16 iload_2
17 invokespecial #6
20 return



The first opcode instruction at location 0, aload_0, pushes the this reference onto the operand stack. (Remember, the first entry of the local variable table for instance methods and constructors is the this reference.)

The next opcode instruction at location 1, invokespecial, calls the constructor of this class's superclass. Because all classes that do not explicitly extend any other class implicitly inherit from java.lang.Object , the compiler provides the necessary bytecode to invoke this base class constructor. During this opcode, the top value from the operand stack, this, is popped.

The next two opcodes, at locations 4 and 5 push the first two entries from the local variable table onto the operand stack. The first value to be pushed is the this reference. The second value is the first formal parameter to the constructor, strName . These values are pushed in preparation for the putfield opcode instruction at location 6.

The putfield opcode pops the two top values off the stack and stores a reference to strName into the instance data name of the object referenced by this .

The next three opcode instructions at locations 9, 10, and 11 perform the same operation with the second formal parameter to the constructor, num , and the instance variable, idNumber .

The next three opcode instructions at locations 14, 15, and 16 prepare the stack for the storeData method call. These instructions push the this reference, strName , and num , respectively. The this reference must be pushed because an instance method is being called. If the method was declared static, the this reference would not need to be pushed. The strName and num values are pushed since they are the parameters to the storeData method. When the storeData method executes, the this reference, strName , and num , will occupy indexes 0, 1, and 2, respectively, of the local variable table contained in the frame for that method.

Compiler options

The javac compiler provides a few options that you need to know. The first is the -O option. The JDK documentation claims that -O will optimize your code for execution speed. Using -O with the javac compiler with the Sun Java 2 SDK has no effect on the generated code. Previous versions of the Sun javac compiler performed some rudimentary bytecode optimizations, but these have since been removed. The SDK documentation, however, has not been updated. The only reason -O remains as an option is for compatibility with older make files. Therefore, there is currently no reason to use it.

This also means that the bytecode that is generated by the javac compiler is not any better than the code that you write. For example, if you write a loop that contains an invariant, the invariant will not be removed from the loop by the javac compiler. Programmers are used to compilers from other languages that clean up badly written code. Unfortunately, javac does not do this. More importantly, the javac compiler does not perform simple optimizations like loop unrolling, algebraic simplification, strength reduction, and others. To get these benefits and other simple optimizations, the programmer must perform them on the Java source code and not rely on the javac compiler to perform them. There are many techniques you can use to make the Java compiler generate faster and smaller bytecode. Unfortunately, until Java compilers perform them, you must implement them yourself to achieve their benefits.

The javac compiler also supplies the -g and -g:none options. The -g option tells the compiler to generate all the debugging information. The -g:none option tells the compiler to generate no debugging information. Compiling with -g:none generates the smallest possible .class file. Therefore, this option should be used when trying to generate the smallest possible .class files prior to deployment.

Java debuggers

One very useful feature that I have yet to see in a Java debugger is a disassembly view similar to that of a C or C++ debugger. Disassembling Java code would reveal the bytecode, much like disassembling C or C++ code reveals assembler code. In addition to this feature, another useful feature could be the ability to single step through the bytecode, executing one opcode at a time.

This level of functionality would allow the programmer to see, first hand, the bytecode generated by the Java compiler as well as step through it during debugging. The more information a programmer has about the code generated and executed, the better chance there is of avoiding problems. This type of debugger feature would also encourage programmers to look at, and understand, the bytecode that is executing for their source code.

Thursday, September 6, 2007

Server-side web programming

Web applications are client/server applications. The web browser is the client. The server is a program running on some computer which is identified by a number called the port to distinguish it from other server programs. Clients access the server program via the pair (server,port) called a socket. The browser client (as well as other client programs) initiates the interaction with a URL request:
protocol://data_source

where the protocol is any number of possiblities, including http, file, https, ftp, etc. The data_source can be any number of things from a regular file on the client's machine to a file or program on some server such as these:
file://file
http://server/dir1/dir2/file
http://server/dir1/program
http://server:port/file (server running on alternate port)

The protocol normally dictates the port, but we can specify it if it's different than the usual one. If the target file is a directory, then a default file or program is chosen as the source.

Server-side web programming means that an HTTP request from a browser causes the web server to run a program which generates HTML (or other data) and sends it back to the browser. Java uses Servlets and Java Server Pages (JSP) for server-side programming. These two software technologies are Java's contribution to the two primary styles of server-side programming:
HTML code generated entirely by programming: Perl/CGI, Servlets
program code embedded within HTML code: PHP, ASP, JSP
Server-side programming stands in contrast to client-side programming which is usually equated with JavaScript, but can also be effected by Java Applets, Flash, or any others which provide a browser plugin.

Tomcat web server
A Java Servlet is an object that can the executed by an HTTP server due to the invocation of a browser client. This ability is not automatically part of standard web servers like Apache and Microsoft's IIS so we need a specialized web server for that purpose. The Apache open source tomcat web server serves our needs; its website is this:
http://tomcat.apache.org/
In order to permit user access and not to conflict with other web services — the standard web service runs on port 80, a restricted port in UNIX system — tomcat runs on the standard port 8080. The Tomcat web server starts a Java virtual machine (JVM) and handles browser client accesses by executing the servlets in threads created by this JVM which makes the entire web service process very fast, in contrast, say to CGI programming in which each web server activation requires a new process creation.
Eclipse Web applications setup
The Eclipse IDE supports many plugin tools and allows developers to directly create and modify plugins. It's not clear at this stage of development what will be the definitive plugin tool for web development but the so-called webtools development packages found at
http://www.eclipse.org/webtools/
seems like a likely contender. We'll use the webtools current release build, version R-1.5.2-200610261841, which requires eclipse version 3.1.1. The current stable webtools release is 1.5M4, but this requires eclipse version 3.2M4.

The eclipse webtools and support plugins you'll need are these:
wtp-sdk-R-1.5.2-200610261841.zip
emf-sdo-xsd-SDK-2.2.1.zip
GEF-SDK-3.2.1.zip
JEM-SDK-1.2.1.zip

The Apache tomcat web server, currently version 6.0.14, uses this distribution file, also available through the tomcat website:
apache-tomcat-6.0.14.zip

Install Webtools
Assuming that eclipse 3.1.1 is installed as the directory "eclipse", extract these zip archives:
wtp-sdk-R-1.5.2-200610261841.zip
emf-sdo-xsd-SDK-2.2.1.zip
GEF-SDK-3.2.1.zip
JEM-SDK-1.2.1.zip

into the directory containing the eclipse subdirectory (e.g., the C:\ directory in my suggested Windows installation of Eclipse). These zip archives already have eclipse as their top-level directory, and so their contents will be extracted correctly into the eclipse subdirectory.

The zip files extract almost entirely into the features and plugins subdirectories of eclipse. The EMF zip archive contains duplicates of the top-level files epl-v10.html and notice.html You can either let them be overwritten or not — it is unimportant.
Install Tomcat
Unzip the file apache-tomcat-6.0.14.zip into your folder of choice; it creates the subdirectory
apache-tomcat-6.0.14
A good choice for location might be the same directory holding eclipse.
Tomcat Server Setup in Eclipse
Open Eclipse and select New Other. You should see quite a number of new categories now available due to the plugin additions.

To create the Tomcat server:
Open the Server category, select the Server entry within and click Next.
In the Define a New Server window, select Apache Tomcat v5.5 Server, click Next.
In the Tomcat Server window, click the Browse button to specify the Tomcat installation directory, apache-tomcat-6.0.14. Click Finish.
Specify the web browser to use
Eclipse has its own internal web browser that can be used to display web content, but you may want to use an external web browser. In eclipse, select:
Window Preferences General Web Browser
It's not clear that the so-called Default System Web Browser will find the right thing. You can add your own external browser if necessary. On a Windows installation, Internet Explorer will be among the list of browsers; you can simply select it, it takes no parameters.

For other browsers, e.g., firefox or mozilla browsers, if already on the list, select it, click Edit, and set the parameters to
-url %URL%

If not in the list, click New, fill in the Name (e.g., "Firefox"); browse to find the location of the executable and finally set the parameters as above.
The structure of a Servlet
The activation of a servlet is initiated by a client-side (browser) request. There are two types of requests: GET and POST. GET requests are most standard and always activated by typing any URL into a browser. GET requests are also those in which you see parameters delivered in the URL itself after the "?" character, a portion called the query string. POST requests are less frequent and are normally initiated by HTML forms.

A Java Servlet is an extension of the javax.servlet.http.HttpServlet. A GET or POST request activates one of the two built-in functions: doGet or doPost, respectively. Many server-side programs do not need to differentiate between these two activations and it is often common to merge the behaviors of these activations.
Servlet template
import java.io.*; // for PrintWriter, IOException
import javax.servlet.*; // for Servlet*
import javax.servlet.http.*; // for HttpServlet*

public class MyServlet extends HttpServlet implements Servlet
{
protected void
doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/* ... */
}

protected void
doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/* ... */
}
}

Typical content for the doGet or doPost function is as follows:
response.setContentType("text/html");
PrintWriter out = response.getWriter();

Sunday, September 2, 2007

Hibernate

What is Hibernate?
Hibernate 3.0, the latest Open Source persistence technology at the heart of J2EE EJB 3.0 is available for download from Hibernet.org.The Hibernate 3.0 core is 68,549 lines of Java code together with 27,948 lines of unit tests, all freely available under the LGPL, and has been in development for well over a year. Hibernate maps the Java classes to the database tables. It also provides the data query and retrieval facilities that significantly reduces the development time. Hibernate is not the best solutions for data centric applications that only uses the stored-procedures to implement the business logic in database. It is most useful with object-oriented domain modes and business logic in the Java-based middle-tier. Hibernate allows transparent persistence that enables the applications to switch any database. Hibernate can be used in Java Swing applications, Java Servlet-based applications, or J2EE applications using EJB session beans.

Features of Hibernate

  • Hibernate 3.0 provides three full-featured query facilities: Hibernate Query Language, the newly enhanced Hibernate Criteria Query API, and enhanced support for queries expressed in the native SQL dialect of the database.
  • Filters for working with temporal (historical), regional or permissioned data.
  • Enhanced Criteria query API: with full support for projection/aggregation and subselects.
  • Runtime performance monitoring: via JMX or local Java API, including a second-level cache browser.
  • Eclipse support, including a suite of Eclipse plug-ins for working with Hibernate 3.0, including mapping editor, interactive query prototyping, schema reverse engineering tool.
  • Hibernate is Free under LGPL: Hibernate can be used to develop/package and distribute the applications for free.
  • Hibernate is Scalable: Hibernate is very performant and due to its dual-layer architecture can be used in the clustered environments.
  • Less Development Time: Hibernate reduces the development timings as it supports inheritance, polymorphism, composition and the Java Collection framework.
  • Automatic Key Generation: Hibernate supports the automatic generation of primary key for your.
  • JDK 1.5 Enhancements: The new JDK has been released as a preview earlier this year and we expect a slow migration to the new 1.5 platform throughout 2004. While Hibernate3 still runs perfectly with JDK 1.2, Hibernate3 will make use of some new JDK features. JSR 175 annotations, for example, are a perfect fit for Hibernate metadata and we will embrace them aggressively. We will also support Java generics, which basically boils down to allowing type safe collections.
  • EJB3-style persistence operations: EJB3 defines the create() and merge() operations, which are slightly different to Hibernate's saveOrUpdate() and saveOrUpdateCopy() operations. Hibernate3 will support all four operations as methods of the Session interface.
  • Hibernate XML binding enables data to be represented as XML and POJOs interchangeably.
  • The EJB3 draft specification support for POJO persistence and annotations.

In this lesson you will learn the architecture of Hibernate. The following diagram describes the high level architecture of hibernate:

The above diagram shows that Hibernate is using the database and configuration data to provide persistence services (and persistent objects) to the application.

To use Hibernate, it is required to create Java classes that represents the table in the database and then map the instance variable in the class with the columns in the database. Then Hibernate can be used to perform operations on the database like select, insert, update and delete the records in the table. Hibernate automatically creates the query to perform these operations.

Hibernate architecture has three main components:

· Connection Management
Hibernate Connection management service provide efficient management of the database connections. Database connection is the most expensive part of interacting with the database as it requires a lot of resources of open and close the database connection.

· Transaction management:
Transaction management service provide the ability to the user to execute more than one database statements at a time.

· Object relational mapping:
Object relational mapping is technique of mapping the data representation from an object model to a relational data model. This part of the hibernate is used to select, insert, update and delete the records form the underlying table. When we pass an object to a Session.save() method, Hibernate reads the state of the variables of that object and executes the necessary query.

Hibernate is very good tool as far as object relational mapping is concern, but in terms of connection management and transaction management, it is lacking in performance and capabilities. So usually hibernate is being used with other connection management and transaction management tools. For example apache DBCP is used for connection pooling with the Hibernate.

Hibernate provides a lot of flexibility in use. It is called "Lite" architecture when we only uses the object relational mapping component. While in "Full Cream" architecture all the three component Object Relational mapping, Connection Management and Transaction Management) are used.

In this section I will show you how to create a simple program to insert record in MySQL database. You can run this program from Eclipse or from command prompt as well. I am assuming that you are familiar with MySQL and Eclipse environment.

Configuring Hibernate
In this application Hibernate provided connection pooling and transaction management is used for simplicity. Hibernate uses the hibernate.cfg.xml to create the connection pool and setup required environment.

Here is the code:


"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">



com.mysql.jdbc.Driver
jdbc:mysql://localhost/hibernatetutorial
root

10
true
org.hibernate.dialect.MySQLDialect
update

contact.hbm.xml"/>

In the above configuration file we specified to use the "hibernatetutorial" which is running on localhost and the user of the database is root with no password. The dialect property is org.hibernate.dialect.MySQLDialect which tells the Hibernate that we are using MySQL Database. Hibernate supports many database. With the use of the Hibernate (Object/Relational Mapping and Transparent Object Persistence for Java and SQL Databases), we can use the following databases dialect type property:

  • DB2 - org.hibernate.dialect.DB2Dialect
  • HypersonicSQL - org.hibernate.dialect.HSQLDialect
  • Informix - org.hibernate.dialect.InformixDialect
  • Ingres - org.hibernate.dialect.IngresDialect
  • Interbase - org.hibernate.dialect.InterbaseDialect
  • Pointbase - org.hibernate.dialect.PointbaseDialect
  • PostgreSQL - org.hibernate.dialect.PostgreSQLDialect
  • Mckoi SQL - org.hibernate.dialect.MckoiDialect
  • Microsoft SQL Server - org.hibernate.dialect.SQLServerDialect
  • MySQL - org.hibernate.dialect.MySQLDialect
  • Oracle (any version) - org.hibernate.dialect.OracleDialect
  • Oracle 9 - org.hibernate.dialect.Oracle9Dialect
  • Progress - org.hibernate.dialect.ProgressDialect
  • FrontBase - org.hibernate.dialect.FrontbaseDialect
  • SAP DB - org.hibernate.dialect.SAPDBDialect
  • Sybase - org.hibernate.dialect.SybaseDialect
  • Sybase Anywhere - org.hibernate.dialect.SybaseAnywhereDialect

The contact.hbm.xml"/> property is the mapping for our contact table.

Writing First Persistence Class
Hibernate uses the Plain Old Java Objects (POJOs) classes to map to the database table. We can configure the variables to map to the database column. Here is the code for Contact.java:

package roseindia.tutorial.hibernate;

/**
* @author Deepak Kumar
*
* Java Class to map to the datbase Contact Table
*/
public class Contact {
private String firstName;
private String lastName;
private String email;
private long id;

/**
* @return Email
*/
public String getEmail() {
return email;
}

/**
* @return First Name
*/
public String getFirstName() {
return firstName;
}

/**
* @return Last name
*/
public String getLastName() {
return lastName;
}

/**
* @param string Sets the Email
*/
public void setEmail(String string) {
email = string;
}

/**
* @param string Sets the First Name
*/
public void setFirstName(String string) {
firstName = string;
}

/**
* @param string sets the Last Name
*/
public void setLastName(String string) {
lastName = string;
}

/**
* @return ID Returns ID
*/
public long getId() {
return id;
}

/**
* @param l Sets the ID
*/
public void setId(long l) {
id = l;
}

}

Mapping the Contact Object to the Database Contact table
The file contact.hbm.xml is used to map Contact Object to the Contact table in the database. Here is the code for contact.hbm.xml:


"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

















Setting Up MySQL Database
In the configuration file(hibernate.cfg.xml) we have specified to use hibernatetutorial database running on localhost. So, create the databse ("hibernatetutorial") on the MySQL server running on localhost.

Developing Code to Test Hibernate example
Now we are ready to write a program to insert the data into database. We should first understand about the Hibernate's Session. Hibernate Session is the main runtime interface between a Java application and Hibernate. First we are required to get the Hibernate Session.SessionFactory allows application to create the Hibernate Sesssion by reading the configuration from hibernate.cfg.xml file. Then the save method on session object is used to save the contact information to the database:

session.save(contact)

Here is the code of FirstExample.java


package roseindia.tutorial.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;


/**
* @author Deepak Kumar
*
* http://www.roseindia.net
* Hibernate example to inset data into Contact table
*/
public class FirstExample {
public static void main(String[] args) {
Session session = null;

try{
// This step will read hibernate.cfg.xml and prepare hibernate for use
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
session =sessionFactory.openSession();
//Create new instance of Contact and set values in it by reading them from form object
System.out.println("Inserting Record");
Contact contact = new Contact();
contact.setId(3);
contact.setFirstName("Deepak");
contact.setLastName("Kumar");
contact.setEmail("deepak_38@yahoo.com");
session.save(contact);
System.out.println("Done");
}catch(Exception e){
System.out.println(e.getMessage());
}finally{
// Actual contact insertion will happen at this step
session.flush();
session.close();

}

}
}

In the next section I will show how to run and test the program.

Hibernate is free open source software it can be download from http://www.hibernate.org/6.html. Visit the site and download Hibernate 3.0. You can download the Hibernate and install it yourself. But I have provided very thing in one zip file. Download the example code and library from here and extract the content in your favorite directory say "C:\hibernateexample". Download file contains the Eclipse project. To run the example you should have the Eclipse IDE on your machine. Start the Eclipse project and select Java Project as shown below.

Click on "Next" button. In the new screen, enter "hibernateexample" as project name and browse the extracted directory "C:\hibernateexample".

Click on "Next" button. In the next screen leave the output folder as default "hibernateexample/bin" .

Click on the "Finish" button.

Now Open the FirstExample.java in the editor as show below.

Copy contact.hbm.xml, and hibernate.cfg.xml in the bin directory of the project using windows explorer. To run the example select Run-> Run As -> Java Application from the menu bar as shown below.

This will run the Hibernate example program in Eclipse following output will displayed on the Eclipse Console.

In this section I showed you how to run the our first Hibernate 3.0 example.

In the last example we created contact.hbm.xml to map Contact Object to the Contact table in the database. Now let's understand the each component of the mapping file.

To recall here is the content of contact.hbm.xml:


"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

















Hibernate mapping documents are simple xml documents. Here are important elements of the mapping file:.

  1. element
    The first or root element of hibernate mapping document is element. Between the <hibernate-mapping> tag class element(s) are present.
  2. element
    The element maps the class object with corresponding entity in the database. It also tells what table in the database has to access and what column in that table it should use. Within one element, several mappings are possible.
  3. element
    The element in unique identifier to identify and object. In fact element map with the primary key of the table. In our code :

    primary key maps to the ID field of the table CONTACT. The attributes of the id element are:
    • name: The property name used by the persistent class.
    • column: The column used to store the primary key value.
    • type: The Java data type used.
    • unsaved-value: This is the value used to determine if a class has been made persistent. If the value of the id attribute is null, then it means that this object has not been persisted.
  4. element
    The method is used to generate the primary key for the new record. Here is some of the commonly used generators :

    * Increment - This is used to generate primary keys of type long, short or int that are unique only. It should not be used in the clustered deployment environment.

    * Sequence - Hibernate can also use the sequences to generate the primary key. It can be used with DB2, PostgreSQL, Oracle, SAP DB databases.

    * Assigned - Assigned method is used when application code generates the primary key.

  5. element
    The property elements define standard Java attributes and their mapping into database schema. The property element supports the column child element to specify additional properties, such as the index name on a column or a specific column type.

In this lesson you will learn about hibernate method in detail. Hibernate generator element generates the primary key for new record. There are many options provided by the generator method to be used in different situations.

The element

This is the optional element under element. The element is used to specify the class name to be used to generate the primary key for new record while saving a new record. The element is used to pass the parameter (s) to the class. Here is the example of generator element from our first application:

In this case element do not generate the primary key and it is required to set the primary key value before calling save() method.

Here are the list of some commonly used generators in hibernate:

Generator

Description

increment

It generates identifiers of type long, short or int that are unique only when no other process is inserting data into the same table. It should not the used in the clustered environment.

identity

It supports identity columns in DB2, MySQL, MS SQL Server, Sybase and HypersonicSQL. The returned identifier is of type long, short or int.

sequence

The sequence generator uses a sequence in DB2, PostgreSQL, Oracle, SAP DB, McKoi or a generator in Interbase. The returned identifier is of type long, short or int

hilo

The hilo generator uses a hi/lo algorithm to efficiently generate identifiers of type long, short or int, given a table and column (by default hibernate_unique_key and next_hi respectively) as a source of hi values. The hi/lo algorithm generates identifiers that are unique only for a particular database. Do not use this generator with connections enlisted with JTA or with a user-supplied connection.

seqhilo

The seqhilo generator uses a hi/lo algorithm to efficiently generate identifiers of type long, short or int, given a named database sequence.

uuid

The uuid generator uses a 128-bit UUID algorithm to generate identifiers of type string, unique within a network (the IP address is used). The UUID is encoded as a string of hexadecimal digits of length 32.

guid

It uses a database-generated GUID string on MS SQL Server and MySQL.

native

It picks identity, sequence or hilo depending upon the capabilities of the underlying database.

assigned

lets the application to assign an identifier to the object before save() is called. This is the default strategy if no element is specified.

select

retrieves a primary key assigned by a database trigger by selecting the row by some unique key and retrieving the primary key value.

foreign

uses the identifier of another associated object. Usually used in conjunction with a primary key association.

As we have seen in the last section that the increment class generates identifiers of type long, short or int that are unique only when no other process is inserting data into the same table. In this lesson I will show you how to write running program to demonstrate it. You should not use this method to generate the primary key in case of clustured environment.

In this we will create a new table in database, add mappings in the contact.hbm.xml file, develop the POJO class (Book.java), write the program to test it out.

Create Table in the mysql database:
User the following sql statement to create a new table in the database.
CREATE TABLE `book` (
`id` int(11) NOT NULL default '0',
`bookname` varchar(50) default NULL,
PRIMARY KEY (`id`)
) TYPE=MyISAM

Developing POJO Class (Book.java)
Book.java is our POJO class which is to be persisted to the database table "book".

/**
* @author Deepak Kumar
*
* http://www.roseindia.net
* Java Class to map to the database Book table
*/
package roseindia.tutorial.hibernate;


public class Book {
private long lngBookId;
private String strBookName;

/**
* @return Returns the lngBookId.
*/
public long getLngBookId() {
return lngBookId;
}
/**
* @param lngBookId The lngBookId to set.
*/
public void setLngBookId(long lngBookId) {
this.lngBookId = lngBookId;
}
/**
* @return Returns the strBookName.
*/
public String getStrBookName() {
return strBookName;
}
/**
* @param strBookName The strBookName to set.
*/
public void setStrBookName(String strBookName) {
this.strBookName = strBookName;
}
}

Adding Mapping entries to contact.hbm.xml
Add the following mapping code into the contact.hbm.xml file









Note that we have used increment for the generator class. *After adding the entries to the xml file copy it to the bin directory of your hibernate eclipse project(this step is required if you are using eclipse).

Write the client program and test it out
Here is the code of our client program to test the application.

/**
* @author Deepak Kumar
*
* http://www.roseindia.net
* Example to show the increment class of hibernate generator element to
* automatically generate the primay key
*/
package roseindia.tutorial.hibernate;

//Hibernate Imports
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;


public class IdIncrementExample {
public static void main(String[] args) {
Session session = null;

try{
// This step will read hibernate.cfg.xml and prepare hibernate for use
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
session =sessionFactory.openSession();

org.hibernate.Transaction tx = session.beginTransaction();

//Create new instance of Contact and set values in it by reading them from form object
System.out.println("Inserting Book object into database..");
Book book = new Book();
book.setStrBookName("Hibernate Tutorial");
session.save(book);
System.out.println("Book object persisted to the database.");
tx.commit();
session.flush();
session.close();
}catch(Exception e){
System.out.println(e.getMessage());
}finally{
}

}
}

To test the program Select Run->Run As -> Java Application from the eclipse menu bar. This will create a new record into the book table.

In this tutorial we will show how to update a row with new information by retrieving data from the underlying database using the hibernate. Lets first write a java class to update a row to the database.

Create a java class:
Here is the code of our java file (UpdateExample.java), where we will update a field name "InsuranceName" with a value="Jivan Dhara" from a row of the insurance table.

Here is the code of delete query: UpdateExample .java

package roseindia.tutorial.hibernate;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class UpdateExample {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Session sess = null;
try {
SessionFactory fact = new Configuration().configure().buildSessionFactory();
sess = fact.openSession();
Transaction tr = sess.beginTransaction();
Insurance ins = (Insurance)sess.get(Insurance.class, new Long(1));
ins.setInsuranceName("Jivan Dhara");
ins.setInvestementAmount(20000);
ins.setInvestementDate(new Date());
sess.update(ins);
tr.commit();
sess.close();
System.out.println("Update successfully!");
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
}

Download this code.

Output:

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).

log4j:WARN Please initialize the log4j system properly.

Hibernate: select insurance0_.ID as ID0_0_, insurance0_.insurance_name as insurance2_0_0_, insurance0_.invested_amount as invested3_0_0_, insurance0_.investement_date as investem4_0_0_ from insurance insurance0_ where insurance0_.ID=?

Hibernate: update insurance set insurance_name=?, invested_amount=?, investement_date=? where ID=?

Update successfully!

Hibernate Query Language or HQL for short is extremely powerful query language. HQL is much like SQL and are case-insensitive, except for the names of the Java Classes and properties. Hibernate Query Language is used to execute queries against database. Hibernate automatically generates the sql query and execute it against underlying database if HQL is used in the application. HQL is based on the relational object models and makes the SQL object oriented. Hibernate Query Language uses Classes and properties instead of tables and columns. Hibernate Query Language is extremely powerful and it supports Polymorphism, Associations, Much less verbose than SQL.

There are other options that can be used while using Hibernate. These are Query By Criteria (QBC) and Query BY Example (QBE) using Criteria API and the Native SQL queries. In this lesson we will understand HQL in detail.

Why to use HQL?

  • Full support for relational operations: HQL allows representing SQL queries in the form of objects. Hibernate Query Language uses Classes and properties instead of tables and columns.
  • Return result as Object: The HQL queries return the query result(s) in the form of object(s), which is easy to use. This elemenates the need of creating the object and populate the data from result set.
  • Polymorphic Queries: HQL fully supports polymorphic queries. Polymorphic queries results the query results along with all the child objects if any.
  • Easy to Learn: Hibernate Queries are easy to learn and it can be easily implemented in the applications.
  • Support for Advance features: HQL contains many advance features such as pagination, fetch join with dynamic profiling, Inner/outer/full joins, Cartesian products. It also supports Projection, Aggregation (max, avg) and grouping, Ordering, Sub queries and SQL function calls.
  • Database independent: Queries written in HQL are database independent (If database supports the underlying feature).

Understanding HQL Syntax
Any Hibernate Query Language may consist of following elements:

  • Clauses
  • Aggregate functions
  • Subqueries

Clauses in the HQL are:

Aggregate functions are:

Subqueries
Subqueries are nothing but its a query within another query. Hibernate supports Subqueries if the underlying database supports it.

In this lesson we will create insurance table and populate it with the data. We will use insurance table for rest of the HQL tutorial.

To create the insurance table and insert the sample data, run the following sql query:








 
/*Table structure for table `insurance` */
 
drop table if exists `insurance`;
 
CREATE TABLE `insurance` (
  `ID` int(11) NOT NULL default '0',
  `insurance_name` varchar(50) default NULL,
  `invested_amount` int(11) default NULL,
  `investement_date` datetime default NULL,
  PRIMARY KEY  (`ID`)
) TYPE=MyISAM;
 
/*Data for the table `insurance` */
 
insert into `insurance` values (1,'Car Insurance',1000,'2005-01-05 00:00:00');
insert into `insurance` values (2,'Life Insurance',100,'2005-10-01 00:00:00');
insert into `insurance` values (3,'Life Insurance',500,'2005-10-15 00:00:00');
insert into `insurance` values (4,'Car Insurance',2500,'2005-01-01 00:00:00');
insert into `insurance` values (5,'Dental Insurance',500,'2004-01-01 00:00:00');
insert into `insurance` values (6,'Life Insurance',900,'2003-01-01 00:00:00');
insert into `insurance` values (7,'Travel Insurance',2000,'2005-02-02 00:00:00');
insert into `insurance` values (8,'Travel Insurance',600,'2005-03-03 00:00:00');
insert into `insurance` values (9,'Medical Insurance',700,'2005-04-04 00:00:00');
insert into `insurance` values (10,'Medical Insurance',900,'2005-03-03 00:00:00');
insert into `insurance` values (11,'Home Insurance',800,'2005-02-02 00:00:00');
insert into `insurance` values (12,'Home Insurance',750,'2004-09-09 00:00:00');
insert into `insurance` values (13,'Motorcycle Insurance',900,'2004-06-06 00:00:00');
insert into `insurance` values (14,'Motorcycle Insurance',780,'2005-03-03 00:00:00');

In this lesson we will write example code to select the data from Insurance table using Hibernate Select Clause. The select clause picks up objects and properties to return in the query result set. Here is the query:

Select insurance.lngInsuranceId, insurance.insuranceName, insurance.investementAmount, insurance.investementDate from Insurance insurance

which selects all the rows (insurance.lngInsuranceId, insurance.insuranceName, insurance.investementAmount, insurance.investementDate) from Insurance table.

Hibernate generates the necessary sql query and selects all the records from Insurance table. Here is the code of our java file which shows how select HQL can be used:


package roseindia.tutorial.hibernate;

import org.hibernate.Session;
import org.hibernate.*;
import org.hibernate.cfg.*;

import java.util.*;

/**
* @author Deepak Kumar
*
* http://www.roseindia.net
* HQL Select Clause Example
*/
public class SelectClauseExample {
public static void main(String[] args) {
Session session = null;

try{
// This step will read hibernate.cfg.xml and prepare hibernate for use
SessionFactory sessionFactory = new Configuration().configure()
.buildSessionFactory();
session =sessionFactory.openSession();

//Create Select Clause HQL
String SQL_QUERY ="Select insurance.lngInsuranceId,insurance.insuranceName," +
"insurance.investementAmount,insurance.investementDate from Insurance insurance";
Query query = session.createQuery(SQL_QUERY);
for(Iterator it=query.iterate();it.hasNext();){
Object[] row = (Object[]) it.next();
System.out.println("ID: " + row[0]);
System.out.println("Name: " + row[1]);
System.out.println("Amount: " + row[2]);
}

session.close();
}catch(Exception e){
System.out.println(e.getMessage());
}finally{
}
}
}

http://www.roseindia.net/hibernate/index.shtml