Tuesday, September 4, 2012

My experiences with Hibernate - Part 1

Hibernate is arguably the most popular ORM tool which is not only widely used and well documented but also motivator for other ORM standards like JPA. There is one side of camp which hates ORM in general (championed by Ted Neward in early 2006 and propagated by his article "The Vietnam of Computer Science"). I read that article long way back in 2007 and thought in horror"My God ! Why should I bother about ORM in general. I am happy with my JDBC and cluttering my code with mapping code". But as things turned out, ORM tools slowly gained ground and now a days majority of Enterprise applications use some sort of ORM to speed up the development work. So I begin to have a taste of Hibernate during work and personal projects. Hibernate does a great job when you begin to appreciate the impedance mismatch betweeen object model and relational model it's trying to solve ( though that's impossible to completely solve. To know why read the article mentioned above). Also its well documented and an exceptionally well written book "Hibernate in Action" (now in second edition with title "Java Persistence with Hibernate"). The mailing list is helpful and there are lots of sample examples.
However while advocating Hibernate to anyone I had a feeling inside and I could not give word to that  until one day when I stumbled upon a phrase by ever popular Joel. He mentioned about "Leaky Abstractions" and when I read that I was convinced that is what ORM and in general Hibernate is. In summary what "Leaky Abstraction" refers to is an abstraction which promised to act like an abstraction to its users but behind the scenes requires the users to understand about its details ( which is violation of  the principle of abstraction).
I am not taking away anything from Hibernate and maintain that it a well written tool full of features. But just a word of caution. If you think you just need to know what to use in Hibernate for use case, you will shoot yourself in your foot. You have to keep an eye on what hibernate is doing behind the scene and how to use it myriads of configuration settings. If you do not you will loose several hours in debugging it. I would suggest if you foresee yourself using Hibernate or JPA for a considerable time in your projects, then spend some time in soaking in some basic and advanced concepts from the book "Java persistence with Hibernate". You won't regret this.

I coming weeks I would be listing some of the concepts in Hibernate which are bit confusing and at times misleading. These posts would not be necessarily long ones and some may even be bullet points but they will be helpful to understand more about the inner workings of Hibernate.

JTA Internals - Part 1

Transaction management is one of the most important part of design of an application which requires adherence to ACID properties.

Java EE provides JTA specification to manage distributed transactions. However there are many popular framworks  like Spring framework which provide integration to JTA as well as  old school JDBC (native database transactions through the JDBC Connection API -  more commonly known as resource local transaction). On the top of it if you are using an ORM (like Hibernate) then there is another layer on top of that. Couple that with concepts of transactional second level caches in ORM's like Hibernate in JTA environment. So just knowing about the ACID properties of transaction is not enough to understand the infrastructure. Also as always if you need to debug any transaction related issue you need to have  knowledge of what goes on behind the scenes.

For those who are not satisfied with just using an API but want to uncover the internals I will be writing up a bit of detailed information in the coming weeks. This is the first part of the series.

JTA (Java Transaction API) is a part of Java EE specification and is defined as
standard Java interfaces between a transaction manager and the parties involved in a distributed transaction system: the resource manager, the application server, and the transactional applications.
Let's see each of the parties here in a bit more details. But before that it would be really good to explain a bit about some key interfaces supplied by JTA (there are only very few interfaces to name).

UserTransaction

This is the interface used by your application code to manage the transaction boundaries and commit and rollback. In application server environment, the implementation of this interface is bound usually to jndi and the code can use lookup or dependency injection to get hold of this.
UserTransaction ut = getUserTransaction();
ut.begin();
......
ut.commit();
} catch (Exception e) {
ut.rollback();
}
TransactionManager

This is the interface used by the application server code which provides the infrastructure related to transaction management. Your application can be configured to use the application server transaction facility using declarative approach  -  meaning you tell your application server through configuration that your application code requires transactions at such and such place. To begin and end the transaction, the application server uses code which is similar to the above but this code is hidden in application server code managing the transaction infrastructure so your classes don't have to write this.
Usually the implementation for UserTransaction and TransactionManager Interfaces are done in the same implementation class as there are just few methods extra in TransactionManager interface (though this may vary from implementations)
Also this implementaion is bound to jndi from where it is looked up by the application server.

Transaction

This is the interface representing the transaction associated with a current thread.
It is crucial to understand a bit of details of how this is used although you wont be directly using this interface in your code. Also it will help you in understanding what happens under the covers when your application uses other framework layers such as Spring and Hibernate.

So in either case ( programmatic or declarative transaction management), when a transaction begins ( either by your application code calling UserTransaction begin method or TransactionManager begin method is called by application server code), a Transaction object is created and bound to the current thread using Threadlocal variable approach. If there is an active Transaction object bound to the current thread then a transaction is said to be in progress. Any transaction aware code can check the existence of this transaction to see if there is a  transaction in progress. For e.g., when a connection is requested from a transaction aware implementation of DataSource , it checks the existence of a transaction and enlists the resource in transaction using Transaction interface enlist method.

This check is also essential for many operations in transaction and more specifically when deciding for transaction propagation "required". For required propagation, if there is a transaction already in progress in the current thread then no new transaction is created.