Installation and configuration

Before Hibernate can be used in an application, the library has to be installed and configured.

Installation of Hibernate

The Hibernate ORM can be downloaded from http://hibernate.org/orm/ as a zip file containing a collection of JAR files that have to be added to the classpath manually.

As Hibernate depends on a couple of other open source libraries, it is recommended to let a build tool like Maven or Gradle resolve the dependencies automatically by adding a dependency to the hibernate-core module of the build file.

Note

The examples in this chapter refer to the Version 4.3.7.Final of Hibernate ORM.

Configuring Hibernate

Before Hibernate can be used, it has to be configured with the correct connection parameters and the database driver to use. This can be done either by using an XML file (hibernate.cfg.xml) or a properties file (hibernate.properties). In both cases, the file should be stored in the classpath, normally in src/main/resources/, if the Mavens standard directory structure is used.

A basic configuration in the XML format could look like this:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
  "-//Hibernate/Hibernate Configuration DTD//EN"
  "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="connection.driver_class">
      org.postgresql.Driver
    </property>
    <property name="connection.url">
      jdbc:postgresql://localhost/car_portal
    </property>
    <property name="connection.username">
      car_portal_app
    </property>
    <property name="connection.password"></property>
    <property name="dialect">
      org.hibernate.dialect.PostgreSQL9Dialect
    </property>
    <property name="show_sql">true</property>
  </session-factory>
</hibernate-configuration>

When using a properties file, the configuration would be written in a name=value format (such as connection.username=car_portal_app).

In addition to specifying the parameters needed to connect to the database, two optional settings are configured in the example:

  • dialect: This configures the specific SQL variant of the database. In most cases, Hibernate is able to resolve the used dialect by itself.
  • show_sql: When this is set to true, Hibernate logs all the executed SQL statements to the console.

A complete list of the optional configuration properties is given in chapter 3.4 of the Hibernate reference documentation (http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/).

Getting a session from the SessionFactory

Before a Java application can interact with the persistence store, it has to open a session. A session is a single-threaded object that holds a JDBC connection to the database. As with connections, a session should be closed as soon as it is no longer needed. A new session can be created by calling openSession() on the SessionFactory.

A SessionFactory is an immutable, thread-safe factory for session instances. It is recommended to instantiate it as a singleton object with the application-global scope.

Often, it is helpful to create a reusable helper class that provides the SessionFactory:

public class SessionFactoryHelper{
  private static final SessionFactory sessionFactory = createSessionFactory();

  private static SessionFactory createSessionFactory(){
    Configuration configuration = new Configuration().configure();
    StandardServiceRegistry registry =
      new StandardServiceRegistryBuilder()
      .applySettings(configuration.getProperties())
      .build();
    return configuration.buildSessionFactory(registry);
  }

  public static SessionFactory getSessionFactory(){
    return sessionFactory;
  }
}

Upon the first invocation of the SessionFactoryHelper, createSessionFactory is called to instantiate the sessionFactory object.

First, the configuration is loaded from the standard configuration file by calling configure on an instance of Configuration. The loaded properties are then used to create an instance of StandardServiceRegistry.

A ServiceRegistry instance manages services, which provide functionality in a pluggable manner. An example of a service is ConnectionProvider, which is an interface declaring methods for obtaining and releasing connections. Hibernate always references this interface, while the actual implementation is managed by the registry.

The ServiceRegistry is then used again to let the Configuration object build the SessionFactory.

Once this is done, the factory can be obtained by calling the getSessionFactory method.

Mapping classes to tables

In order to allow Hibernate to store objects in a table, a mapping between the Java class that represents the object and the table that it will be stored in has to be configured.

This can either be done by creating a mapping in the XML format or by adding annotations to an entity-class. In both cases, the mapping has to be added to the session-factory section in the configuration-file:

<mapping resource="Account.hbm.xml"/>
<mapping class="carportal.Account"/>

The first entry adds a mapping in the XML format, while the second entry specifies the fully-qualified name of an annotated entity class.

It is possible to add multiple mappings to the configuration, and use both methods at the same time.

Creating an entity class

A very basic entity-class for the account table could look like this:

package carportal;

public class Account{
  private int accountID;
  private String firstName;
  private String lastName;
  private String email;
  private String password;
  
  protected Account(){}
}

It contains a private field for each column in the table and a constructor without parameters. Hibernate needs this constructor to create an instance of the entity using Java reflection API.

For usage from within the application, the setter and getter methods for accessing the fields and a public constructor for initializing the entity should be added as needed.

Now, the next step is to configure the mapping.

Creating a mapping file

After creating the entity class, a mapping file (Account.hbm.xml) should be created in src/main/resources/ with the following content:

<hibernate-mapping package="carportal" schema="carportal_app">
  <class name="Account" table="account">
    <id name="accountID" column="account_id">
      <generator class="identity"/>
    </id>
    <property name="firstName" column="first_name"/>
    <property name="lastName" column="last_name"/>
    <property name="email"/>
    <property name="password"/>
  </class>
</hibernate-mapping>

The top level element, hibernate-mapping, sets two optional parameters that define the default package name and the schema to be added to the unqualified class and table names.

Next, the class node maps a class name to the respective table. The table attribute is optional, and defaults to the class name if omitted.

There can be multiple class nodes in a mapping definition.

The mapping of columns to the fields is configured inside the class node using the id and column nodes. There has to be one id node for each primary key column of the table.

All other columns are defined as a property node. These are optional, and can be left out if a column will not be used inside the entity-class.

Both id and property nodes have a name attribute, which specifies the field name of the defined class. They can also have an optional column attribute if the names of the field and column do not match.

Additionally, the id node configures a generator class, which defines how the unique identifiers are created. The generator class can either be given as a shortcut name of one of Hibernate's built-in generators or the class name of an external implementation.

Some of the built-in generators are:

  • Assigned (default): This lets the application assign an identifier before storing an entity.
  • Identity: It uses an identity or serial from the database.
  • Sequence: This uses a sequence from the database. The name of the sequence is configured as a child of the generator node: <paramname="sequence">account_id_seq</param>.
  • UUID: This uses a 128-bit UUID algorithm to create identifiers.

A complete documentation of the XML mapping can be found in Chapter 5, SQL Language, of the Hibernate reference manual.

Using annotation-based mapping

An alternative to XML mapping is to use annotations inside the entity class. Having the mapping inside the class makes it easier to maintain consistency when making changes, as there is only one file to edit.

The annotated version of the Account class looks like this:

package carportal;
import javax.persistence.*;

@Entity
@Table(name = "account")
public class Account{
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "account_id")
  private int accountID;

  @Column(name = "first_name")
  private String firstName;

  @Column(name = "last_name")
  private String lastName;

  private String email;
  private String password;

  @Transient
  private int someInternalValue;

  private Account(){}
}

The following annotations were added to the Account class:

  • @Entity: This tells Hibernate that a Java class is an entity that should be persisted. This is the only annotation that is mandatory in any case.
  • @Table: This configures the name of the target table if it does not match the class name. The schema and catalog name can also be specified by setting the respective attributes of this annotation.
  • @Id: The @Id marks a field as primary key. An entity class must define all the primary keys of a table.
  • @GeneratedValue: This annotation configures the generator class for identifiers, as explained in the previous section. To specify a shortcut name, the strategy attribute is set, while an external generator class is configured using the generator attribute.
  • @Column: This maps a column name to a field name in case they do not match. It is also used to define additional behavior like whether a column should be used in the insert or update statements or whether it can be null.
  • @Transient: All the fields of a class that do not have a corresponding column in the database or that should not be persisted have to be marked transient

The fields email and password are not annotated in the example, as the account table has columns with matching names. Fields without annotations are automatically added to the mapping with a default configuration.

For the remainder of this chapter, annotation-based mapping will be used, as it is more convenient to use and XML mapping is now considered legacy.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.148.180