top button
Flag Notify
    Connect to us
      Site Registration

Site Registration

Hibernate 3 Annotations- Part-1

+1 vote
299 views

Over the years, Hibernate has become close to the defacto standard in the world of Java database persistence. It is powerful, flexible, and boasts excellent performance. In this article, we look at how Java 5 annotations can be used to simplify your Hibernate code and make coding your persistence layer even easier.

Traditionally, Hibernate relies on external XML files for its configuration: database mappings are defined in a set of XML mapping files and loaded at startup time. There are many ways to create these mappings, either automatically, from an existing database schema or Java class model, or by hand. In any case, you can end up with a considerable number of Hibernate mapping files. Alternatively, you can use tools to generate the mapping files from javadoc-style annotations, though this adds an extra step in your build process.

In recent versions of Hibernate, a new, more elegant approach has emerged, based on Java 5 annotations. Using the new Hibernate Annotations library, you can dispense once and for all with your old mapping files--everything is defined as, you guessed it--annotations directly embedded in your Java classes. It turns out that annotations provide a powerful and flexible way of declaring persistence mappings. They are also well supported in recent Java IDEs, with automatic code completion and syntax highlighting.

Hibernate annotations also support the new EJB 3 persistence specifications. These specifications aim at providing a standardized Java persistence mechanism. While Hibernate 3 also provides a few extensions, you can quite easily stick to the standards and code your Hibernate persistence layer using the EJB 3 programming model.

Now, let's take the Hibernate Annotations through its paces.

Installing Hibernate Annotations
To use Hibernate Annotations, you will need at least Hibernate 3.2, and of course Java 5. You can download both Hibernate 3.2 and the Hibernate Annotations library from the Hibernate web site. In addition to the standard Hibernate JARs and dependencies, you will also need the Hibernate Annotations .jar file (hibernate-annotations.jar) Java Persistence API (lib/ejb3-persistence.jar). If you are using Maven, just add the corresponding dependencies into your POM file, as shown here:

 ...
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate</artifactId>
      <version>3.2.1.ga</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-annotations</artifactId>
      <version>3.2.0.ga</version>
    </dependency>
    <dependency>
      <groupId>javax.persistence</groupId>
      <artifactId>persistence-api</artifactId>
      <version>1.0</version>
    </dependency>
    ...

The next step is to obtain a Hibernate session factory. You do this a little differently using Hibernate Annotations, though no earth-shattering modifications are necessary. You simply have to use the AnnotationConfiguration class to set up your session factory:

  sessionFactory = new AnnotationConfiguration().buildSessionFactory();

As usual, you need to declare your persistence classes in the Hibernate configuration file (typically hibernate.cfg.xml), though you use the <mapping> element to declare your persistent classes:
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

        <hibernate-configuration>
          <session-factory>
            <mapping class="com.onjava.modelplanes.domain.PlaneType"/>
            <mapping class="com.onjava.modelplanes.domain.ModelPlane"/>
          </session-factory>
        </hibernate-configuration>

Many Java projects these days use lightweight application frameworks such as Spring. If you are using the Spring framework, you can set up an annotation-based Hibernate session factory easily using the AnnotationSessionFactoryBean class, as shown here:

<!-- Hibernate session factory -->
  <bean id="sessionFactory" 
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
   <property name="dataSource">
     <ref bean="dataSource"/>
   </property>
   <property name="hibernateProperties">
     <props>
       <prop key="hibernate.dialect">org.hibernate.dialect.DerbyDialect</prop>
       <prop key="hibernate.hbm2ddl.auto">create</prop>
       ...
     </props>
   </property>
   <property name="annotatedClasses">
     <list>
       <value>com.onjava.modelplanes.domain.PlaneType</value>
       <value>com.onjava.modelplanes.domain.ModelPlane</value>
       ...
     </list>
   </property>
 </bean>

Our First Persistent Class
Now that we know how to obtain our annotation-backed Hibernate session, let's see what an annotated persistent class looks like.

Annotated persistent classes are ordinary POJOs, just like in any other Hibernate application. Well, almost. You do need to add dependencies to the Java Persistence API (javax.persistence.*), and possibly to the Hibernate Annotations packages (org.hibernate.annotations.*) if you use any Hibernate-specific extensions, but other than that, they are just ordinary POJOs with persistence-related annotations. Here's a simple example:

@Entity
public class ModelPlane {

    private Long id;
    private String name;

    @Id
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

As we said, it's quite simple. The @Entity annotation declares the class to be persistent. The @Id annotation lets you indicate which property is the unique identifier for this class. In fact, you can either persist fields (annotating the member variables) or properties (annotating the getter methods. For the rest of this article, we will use property-based annotations. One of the nice things about annotation-based persistence is its heavy use of default values (following the "convention over configuration" mantra). For example, you don't need to declare every property to be persistent--any property will be assumed to be persistent unless you tell it otherwise by using the @Transient annotation. This simplifies your code, and also makes for a lot less typing than with the old XML mapping files.

posted May 16, 2014 by Aastha Joshi

  Promote This Article
Facebook Share Button Twitter Share Button LinkedIn Share Button


Related Articles

Continued from Part 1:

Generating Primary Keys
One thing Hibernate is good at is automatically generating primary keys. The Hibernate/EBJ 3 annotations also provide a rich support for automatic key generation, allowing a variety of strategies. The following example illustrates a frequently used approach, where Hibernate will decide on an appropriate key generation strategy depending on the underlying database:

@Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    public Long getId() {
        return id;
    }

Customizing Table and Field Mappings
By default, Hibernate will map persistent classes to tables and fields with matching names. For example, the above class would map to a table along the following lines:

CREATE TABLE MODELPLANE 
(
    ID long,
    NAME varchar
)

This is fine if you are generating and maintaining the database yourself, and makes your code a lot easier to maintain if you can get away with it. However, it doesn't suit everyone's needs. Some applications need to access external databases, and others may need to confirm to company database naming conventions. If necessary, you can use the @Table and @Column annotations to tailor your persistence mappings, as shown here:
@Entity
@Table(name="T_MODEL_PLANE")
public class ModelPlane {

private Long id;
private String name;

@Id
@Column(name="PLANE_ID")
public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

@Column(name="PLANE_NAME") 
public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

}

This would map to the following table:

CREATE TABLE T_MODEL_PLANE 
(
    PLANE_ID long,
    PLANE_NAME varchar
)

You can also customize your mappings using other table and column attributes. This lets you specify details such as column length, non-null constraints and so forth. Hibernate supports a large number of attributes for these annotations. Here are just a few:

...
    @Column(name="PLANE_ID", length=80, nullable=true)
    public String getName() {
        return name;
    }
    ...

Mapping Relationships
One of the most important, and complex, parts of Java persistence mapping is determining how to map relationships between tables. As elsewhere, Hibernate provides a great deal of flexibility in this area, arguably at the cost of a certain degree of complexity. We will look at a few common cases to get an idea of how this is done using annotations.

One of the most commonly-used relationships are many-to-one relationships. Suppose, in the above example, that each ModelPlane is associated with a PlaneType via a many-to-one relationship (in other words, each model plane is associated with exactly one plane type, although a given plane type can be associated with several model planes). You could map this as follows:

@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
    public PlaneType getPlaneType() {
                    return planeType;
          }

The CascadeType values indicate how Hibernate should handle cascading operations.

Another commonly-used relationship is the opposite of the above: the one-to-many-to-one relationship, also known as a collection. Collections are complex beasts, both in old-style Hibernate mapping and when using annotations, and we'll just be skimming the surface here to give you an idea of hown it's done, For example, in the above example, each PlaneType object may contain a collection of ModelPlanes. You could map this as follows:

 @OneToMany(mappedBy="planeType",
                   cascade=CascadeType.ALL, 
                   fetch=FetchType.EAGER)
    @OrderBy("name")
    public List<ModelPlane> getModelPlanes() {
        return modelPlanes;
    }

Named Queries

One of the nice features of Hibernate is the ability to declare named queries within your mapping files. These queries can then be invoked by name from within the code, which lets you centralize queries and avoids having SQL or HQL code scattered throughout the application.

You can do this with annotations too, using the @NamedQueries and @NamedQuery annotations, as shown here:

@NamedQueries(
 {         
  @NamedQuery(
    name="planeType.findById",
    query="select p from PlaneType p left join fetch p.modelPlanes where id=:id"
  ),
  @NamedQuery(
    name="planeType.findAll",
    query="select p from PlaneType p" 
  ),
  @NamedQuery(
          name="planeType.delete",
          query="delete from PlaneType where id=:id" 
        )  
 }
)

Once defined, you can call them just as you would any other named query.

Conclusion:
Hibernate 3 annotations provides a powerful and elegant API to simplify your Java database persistence code, and we really have only scratched the surface here. You can either choose to stick to the standards, and use the Java Persistence API, or take advantage of the Hibernate-specific extensions, which provide more power and flexibility, at the cost of a certain loss of portability. In any case, by eliminating the need for XML mapping files, using Hibernate annotations allows you to simplify your application maintenance, with the additional advantage of giving you a gentle introduction into the world of EJB 3.

READ MORE

Hibernate framework simplifies the development of java application to interact with the database. Hibernate is an open source, lightweight, ORM (Object Relational Mapping) tool.

 

Benefits of Hibernate

1) Opensource and Lightweight: Hibernate framework is opensource under the LGPL license and lightweight.

2) Fast performance: The performance of hibernate framework is fast because cache is internally used in hibernate framework. There are two types of cache in hibernate framework first level cache and second level cache. First level cache is enabled bydefault.

3) Database Independent query: HQL (Hibernate Query Language) is the object-oriented version of SQL. It generates the database independent queries. So you don't need to write database specific queries. Before Hibernate, If database is changed for the project, we need to change the SQL query as well that leads to the maintenance problem.

4) Automatic table creation: Hibernate framework provides the facility to create the tables of the database automatically. So there is no need to create tables in the database manually.

5) Simplifies complex join: To fetch data form multiple tables is easy in hibernate framework.

6) Provides query statistics and database status: Hibernate supports Query cache and provide statistics about query and database status.

 

Hibernate Architecture

 

  • SessionFactory (org.hibernate.SessionFactory): SessionFactory is an immutable thread-safe cache of compiled mappings for a single database. We can get instance of org.hibernate.Session using SessionFactory.
  • Session (org.hibernate.Session): Session is a single-threaded, short-lived object representing a conversation between the application and the persistent store. It wraps JDBC java.sql.Connectionand works as a factory for org.hibernate.Transaction.
  • Persistent objects: Persistent objects are short-lived, single threaded objects that contains persistent state and business function. These can be ordinary JavaBeans/POJOs. They are associated with exactly one org.hibernate.Session.
  • Transient objects: Transient objects are persistent classes instances that are not currently associated with a org.hibernate.Session. They may have been instantiated by the application and not yet persisted, or they may have been instantiated by a closed org.hibernate.Session.
  • Transaction (org.hibernate.Transaction): Transaction is a single-threaded, short-lived object used by the application to specify atomic units of work. It abstracts the application from the underlying JDBC or JTA transaction. A org.hibernate.Session might span multiple org.hibernate.Transaction in some cases.
  • ConnectionProvider (org.hibernate.connection.ConnectionProvider): ConnectionProvider is a factory for JDBC connections. It provides abstraction between the application and underlying javax.sql.DataSource or java.sql.DriverManager. It is not exposed to application, but it can be extended by the developer.

Go through this video:

https://www.youtube.com/watch?v=SZ8abQ3vmdc&list=PLkcic9ioQcFctEWxNb04JRUNCe-cupo5r

READ MORE
...