In the second part of our series on Hibernate, we will take a close look at its architecture and core classes. We will also cover the different types of queries possible in Hibernate. Finally, we'll use a real world example to illustrate our discussion.
Hibernate: Paving the Path for Queries - Understanding the Architecture (Page 2 of 4 )
When the context of the discussion is architecture, there are at least three points of observation from which the architecture can be discussed. The first point is like observing a structure from the highest level. This level provides the boundaries of interaction between the framework and the application being built using it. Keeping this in mind, let's look at the highest level architecture of Hibernate. Pictorially it is thus:
Hibernate sits between the database and the application. The interaction between the application and Hibernate framework takes place through the persistent objects. As discussed in the previous part, persistent objects represent rows of a table, as the Persistence class itself is the object model of the table. From the diagram it would be obvious that the hibernate.properties and XML mapping play an important part in this interaction.
This observation point tells us only about the interaction. To understand what constitutes Hibernate, one would have to go to the second level observation point. The second level provides a view into the internals of Hibernate. Diagrammatically it is thus:
Here some explanation is required. The ‘constituent components’ of Hibernate are:
The SessionFactory represents a cache of compiled mapping of a single database. This cache is thread-safe as well as immutable. The mappings defined in the XML file are used to create connections to the database. These connections are pooled. The class, in reality, represents the object form of the mappings. SessionFactory class is a client to the ConnectionProvider. It is a factory (or a provider of instances) to the Session class.
In essence the term "session" means a conversion between a client and a server. This remains true in the context of Hibernate, too. Whenever a database connection is obtained, a session is created for the client -- in this case, the application that has the connection. The Session class represents such a session. It is short-lived and single threaded. It also holds a mandatory cache of persistent objects. The main fact to keep in mind is that Session wraps a JDBC connection.
To understand where the JDBC, JTA and JNDI fit accurately into this picture, the observation point has to be at the lowest level. At this level all the abstractions have been revealed. Which layer abstraction forms which part of the JDBC API is very clear at this level. Pictorially speaking it is thus:
From the above diagram it is clear that the framework abstracts out the complexities at the JDBC, JNDI and JTA level. The ConnectionProvider sits underneath the SessionFactory and communicates with the JDBC for obtaining a connection, which is then given to the application as an object of Session. From there on Session communicates with the application and the underlying layer. The Transaction class is the client of the Session class. Once the value of the persistent object within or referenced by the Session is updated, it is the task of the Transaction class to actually update the values of the table row that the persistent object represents. That’s all we need to know about the architecture of Hibernate to get on well with this framework.
I have already discussed the two main core classes of Hibernate. Now it's time to look at some more. They are:
The Transaction class has already come into the picture. Lets have a detailed look at each of the others.
The configuration XML file forms the entry point for the application to start communicating with the Hibernate framework. It is through the Configuration class that this becomes possible. It come into the picture before the SessionFactory class. An instance of Configuration allows the application to specify the configuration and properties file corresponding to the application. Configuration provides an instance of SessionFactory. One specific point to be kept in mind is that Configuration is meant as an initialization-time object. The following statement obtains an instance of the Configuration class:
Configuration cfg = new Configuration();
A new Configuration uses the properties specified in the hibernate.properties file by default.
It is an interface that represents a unit of task completed. It abstracts out the underlying implementation based on JTA, JDBC etc. A Transaction is always associated with a Session. A Transaction is instantiated when the beginTransaction() method of the Session object is invoked. It ends with a call to either the commit() or rollback() methods. A Session may span multiple Transactions. The reason for this is that the notion of Transaction is more fine grained than that of Session. For example, the following statements start and end a Transaction:
Query is an interface that provides object oriented representation of a Hibernate Query. An instance of Query can be obtained by calling the createQuery() method of the Session class. Queries are executed by calling the list(), scroll() or iterate() method. The following creates a Query for selection of all orders from the Order table:
Query query=session.createQuery(“from Order”);
So that brings us to the end of this section. The next section will detail the three different categories of Query provided by Hibernate.