Search This Blog

Wednesday, 28 September 2011

The Hibernate Inheritance Mechanism - 1

Table per Concrete Class + Implicit Polymorphism
 This is the technique with minimum development efforts. The technique follows the below simple steps:
  1. For each concrete class, one table is created. 
  2. All the inherited properties are mapped in each of these tables.
  3. The abstract (base) class is not represented in SQL

Tuesday, 27 September 2011

The Hibernate Inheritance Mechanism - Preview

Inheritance which is one of the pillars of Object Oriented Programming Model isn't a big player in the SQL environment. While Objects can form both IS-A and HAS-A relationships, Tables are only aware of HAS-A  relationships. (for e.g. 1 Person has many Vehicles)

Hibernate provides techniques that allows us to represents Tables via inheritance relationships. Hibernate has 4 different approaches:

Saturday, 24 September 2011

Composite Identifiers

In the previous discussions of identifiers the focus was on implementing surrogate keys as means to uniquely identify the records.
The wikipedia definition of surrogate key states that
"A surrogate key in a database is a unique identifier for either an entity in the modeled world or an object in the database. The surrogate key is not derived from application data."

Wednesday, 21 September 2011

Bidirectional Components

Components in Hibernate can include a back-reference that allows them to link back to their owning Entity. I decided to try this out and for this created a simple Person entity that includes a name and an Address.

Tuesday, 20 September 2011

Creating a Hibernate Custom Type - 4

Let us look at the EnhancedUserType.This interface extends the UserType interface and provides additional methods to allow usage in XML representation. I shall implement a type that will allow saving of Enums directly to the database.

Friday, 16 September 2011

Creating a Hibernate Custom Type - 3

In the previous articles we saw how to create Custom Mapping Types - both implementations of UserType and CompositeUserType. There is the possibility wherein we may need to add some configuration values to our custom types.

Wednesday, 14 September 2011

Creating a Hibernate Custom Type - 2

As seen in the previous blog, the UserType interface does not provide the ability to use the properties of the new Type in Hibernate Queries. For this we need to implement the more powerful CompositeUserType.
Using the same AuditData object from the previous example,

Monday, 12 September 2011

Creating a Hibernate Custom Type - 1

As seen before Hibernate comes with a huge collection of mapping types. These cover a very wide range of types from single bit fields to blobs and clobs.
It is also possible that we would like to retrieve the data in one of our own pre-defined formats. Hibernate supports this by allowing us to define our own customized mapping types.

The Hibernate Types

Hibernate as we know provides the technique to convert the sql data to java objects . In case of XML mappings, hibernate includes a type attribute to indicate the conversion mechanism to be used.

Id Generators - 6

I shall finish my series on generators with the uuid.hex type. Both uuid.hex and uuid refer to the same generator. The uuid generator uses a 128-bit UUID algorithm to generate identifiers of type string, unique within a network (the IP address is used).

Id Generators - 5

I shall cover the select and assigned generators in this article.

select:

This is used when the primary key is to be generated by some database logic. For e.g. the primary key is assigned by a database trigger. As hibernate did not assign the primary key (and it is not a generated value like auto-increment) how does it set the object's id ?

Sunday, 11 September 2011

Id Generators - 4

I shall cover the foreign and guid classes of generators in this post.

Foreign:


The foreign generator is used with objects that do not have their own key assigned to them.These use the identifier of another associated object. They are generally used along with <one-to-one> primary key association.

Id Generators - 3

Let us look at at the native and increment types in this post.

native

Consider the simple POJO person that represents a Person table

Id Generators - 2

Continuing from the previous post, we shall look into hilo and  seqhilo generator types.

hilo

The hilo algorithm, as per the hibernate documentation, is one of the most popular id generation algorithms available.The working involves creating a separate table in the database that is used to help in the key generation. (An alternative approach is available which works on Oracle styled sequences too)

Id Generators - 1

Most tables we create in the database have primary keys. The mapping classes that we create in java include the <id> or <composite-id> attribute to map the primary key.
In case of the <id> attribute, hibernate provides an optional  <generator> element that is used to manage the creation of id values for new records inserted in tables. The generator class actually includes a class attribute which specifies the class (and therefore the technique) used to generate primary keys.

Saturday, 10 September 2011

Dealing with common content in mapping files

In the previous post we looked into component mapping. I created a component for audit fields and added it to my Java POJO class. Everything worked fine, until I observed that the same mapping is done in the scores of other database tables that we create in our application. The same fields are repeatedly added in our java models. The same mappings are created in our hbm files. The process gets repeated continuously.

Creating Components in Hibernate

The Java POJOs that we create need not be composed solely of Primitive types. It is possible to group together value fields into Java classes. Such objects which exist as member fields inside the mapped java classes are called components.
Components are classes (or columns in the table) that do not have their own life-cycle.

The mapping with minimum details

The mapping files are used to map the database table to the java object. For every such class, all the persistent properties have to be mapped. This is true in case of annotations too.
All Mapped classes must declare the primary key column of the database table. The <id> element defines the mapping from that property to the primary key column.

Using Derived properties

Hibernate provides us with the ability to include properties that do not map to any column in the database. These are fields that are calculated based on formula applied on other columns/other tables/ SQL functions/ custom procedures etc. The function is evaluated every time the entity is retrieved from the database. Consider the case where we have a person whose date of birth is saved in the database. Then the age of this person can be represented in the domain object as a derived property

Thursday, 8 September 2011

Enforcing the Rules for naming conventions

There is often a need to enforce strict naming conventions for the database just as we have naming conventions in java. As multiple developers work on different tables in the schema, there is a possibility of each developer following his own naming conventions. To avoid this Hibernate provides us with the NamingStrategy interface, that can be used to enforce naming standards automatically.
The solution requires us to implement our own naming strategy or use several of the provided options.

Save only those that need saving

When the application is started Hibernate will generate CRUD statements for all the mapped tables. For example, if consider the pet table (I have maintained the audit columns added in the previous post.) then from the logs we can see the following:
3719 [main] DEBUG org.hibernate.persister.entity.AbstractEntityPersister  - Stat
ic SQL for entity: com.menagerie.domain.entity.Pet
3719 [main] DEBUG org.hibernate.persister.entity.AbstractEntityPersister  -  Ver
sion select: select ID from PET where ID =? 

Using db generated values

There are scenarios when certain fields in the table can be managed by the database. In such cases we do not need Hibernate to update these fields from the model. One such scenario could be the audit fields. Most tables that we create include properties to manage the audit details. Typical columns found in the tables for auditing purposes are created_by, modified_by created_date and modified_date.

Monday, 5 September 2011

hibernate.hbm2ddl.auto -2

In the last article I used the SchemaExporter tool to create two sample tables. Here I shall explore the tool in more detail.The tool can be enabled by setting the below property in our cfg file:
<property name="hibernate.hbm2ddl.auto">create-drop</property>
Or if we are using hibernate.properties

hibernate.hbm2ddl.auto

In our earlier post we saw how creating the SessionFactory object led to execution of DDL, if the hm2ddl property was configured. The SchemaExport or hbm2ddl can be used to generate DDL from the mapping files( or annotations). According to the Hibernate guide
"The generated schema includes referential integrity constraints, primary and foreign keys, for entity and collection tables. Tables and sequences are also created for mapped identifier generators.You must specify a SQL Dialect via the hibernate.dialect property when using this tool, as DDL is highly vendor-specific."

Configuring via properties or XML ??

The way to run Hibernate is to create a SessionFactory object. The SessionFactory Object is responsible for providing us with Hibernate sessions to perform the various db Operations. In minimal words, the Session factory is responsible for internally managing all db related operations for us. Before using a session factory it has to be configured for use.

And then they were brought to-ogether

Continuing from the last post, now we need to execute the code. This is where we pass over the control to Hibernate and the framework takes the necessary action to create a database based on the information provided in our mapping files. For this we need to create the cfg file.The cfg or configuration file contains all the configuration information that is needed to get Hibernate up and running.This file must also be present on the class-path.
 hibernate.cfg.xml 
<?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>

Creating the Relational from the Objects

Now that the Objects have been created, it is time to match them to Relational aspect of the application or the database tables.
We have an option of creating the database manually through SQL and then associating them with Objects or Classes created. Or we can do it the other way round.
In this case we proceed by first creating our Object world. Hibernate already provides users with the tools to generate the SQL scripts necessary for this purpose. We shall use the same. But the first step would be to create the mappings for Database related tables, columns, constraints etc that would be used.
This can be achieved either by mapping files or via annotations. I shall prefer the longer (but my personal favorite) hbm files for achieving this.

Fleshing out the Models (The java ones :P) - 2

We saw the Object world in our example was composed of People and their Pets. Certain things that I would like to point out in the code from the previous post:
  1. Both objects have been provided with a database identifier although they include separate fields that can validate their uniqueness in the application.
  2. The setter methods for the identifiers have been made private as the design decision is to let hibernate set and manage the Db Identifier.
  3. Care has been taken to avoid using the Db managed identifier in the equals method. The reason for this can be found in the article http://community.jboss.org/wiki/EqualsAndHashCode. (In basic terms: as we are not managing it and the field is dependent on the objects existence in the database it could create a whole lot of null checks and be difficult for unique checks in Sets and Maps).
  4. Care has been taken in the Pets class to avoid referencing the fields of Owner class in the toString/ hash code method. In case lazy loading is being used, this could lead to the execution of a very large number of queries simply for the purpose of toString readability. The same reason is used to avoid pet references in the Owner.toString method.
  5. The Entities thus created do not have to be dumb representations of the database Records. It makes perfect sense to use the richness of Object Oriented Architecture and to provide business methods like Owner.addPet(). The entities need not be restricted to simple getter/setter methods.
Now that we have identified the properties and behavior of our Java model classes, the next step would be to look at the Relational side of the application.

Fleshing out the Models (The java ones :P) - 1

The way people work is that create the database separately and then create their hibernate model classes to work with the tables in the sql.
I decided to follow the process found in tutorials on the net and in the book.
  1. Analyze and identify the domain models.
  2. Create the class that would represent these objects in java.
  3. Create the OR mapping that would link the Java Models with the database Tables.
  4. Let Hibernate generate the DDL and worry about all related considerations.

The unfortunate victim (or what the sensible call Domain Model)

I decided to start with a very simple application. Just two tables that could be later expanded as required.
As I already had a My SQL db installed at my home, I decided to start with the use of their sample Menagerie database.
I decide to build a simple Pet application. It would be composed of Pets and their Owners. Each Owner could have One or more pets. To simplify things I decide to restrict the Pet domain to DOGS only.
First Draft Object Design


In the Beginning (of this blog)

I have been working on Hibernate for the past year. Like all developers I learned along the way and in a haphazard manner. So when I really got the chance to study Hibernate I realized that I have been using the technology in a very flawed manner. So I decided to do what I should have done last year.
I brought a copy of the book "Java Persistence With Hibernate" and started reading it. Not finding the time to read it everyday has resulted in a longish learning curve. I have covered 20 select pages in the last 6 months. (An unsurprising observation, I have made is that all topics covered are related to all difficulties encountered in my every day work.)

So I finally decided to do things the right way. To read and to code. As I have benefited from a large variety of  sites in my learning process, I decided to do the same. Share the knowledge that I gather in the process.
As I myself am on a learning process I can in no way guarantee to be giving any expert knowledge here. All I am trying is to share what I learn. Cheers.