Implementing Hibernate-based Data

Basics

This article describes how to use the Data Hibernate Classes. It assumes that we want to implement a single Business Object Customer with a single string property name.

The BO Interface Class

1
2
3
4
5
6
7
8
9
public interface Customer extends IGeneralBO<Long> {
   /** Property name */
   public static final String NAME = "name";
 
   /** Getter */
   public String getName();
   /** Setter */
   public void setName(String name);
}

The interface derives from IGeneralBO and requires the key class (line 1). Each property needs to be presented with a static constant property name (line 3) and its getter and setter (lines 6 and 8). Mark a getter as @Transient or @NoCopy in case you wish to achieve special bean behaviour.

Creating the Transfer Object

1
2
3
4
5
6
7
8
9
10
11
12
13
public class CustomerDTO extends GeneralDTO<Long> {
 
   private String name;
 
   public String getName() {
      return this.name;
   }
 
   public void setName(String name) {
      this.name = name;
   }
 
}

The transfer object doesn’t need to implement any special interface. However, it is advisable to inherit from GeneralDTO in order to keep compatibility with the rest of the framework. The signature of the class requires the key class of the model object (line 1). You then implement getters and setters for each property that you need to persist in the database with Hibernate. Remember: the DTO is your class for all Hibernate configurations. That’s why the HBM would look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
   <class name="CustomerDTO" table="customers" batch-size="300">
      <id name="id" column="id" type="long">
         <generator class="native"/>
      </id>
 
      <property name="name" type="string" column="name"/>
   </class>
</hibernate-mapping>

The BO Implementation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class CustomerImpl extends AbstractHibernateBO<Long,CustomerDTO> implements Customer {
 
   public CustomerImpl() {
      this(new CustomerDTO());
   }
 
   public CustomerImpl(CustomerDTO dto) {
      super(dto);
   }
 
   public String getName() {
      return getTransferObject().getName();
   }
 
   public void setName(String name) {
      String oldValue = getName();
      getTransferObject().setName(name);
      firePropertyChange(NAME, oldValue, name);
   }
}

The BO Implementation inherits from AbstractHibernateBO and requires the Key Class and the DTO Class as parameters. As this is our major Customer implementation, it implements the Customer interface (line 1).

A default constructor is always required (line 3). Additionally, you should add a 2nd constructor using a given DTO as the transfer object (line 7).

Getter (line 11) and Setter (line 15) both use the underlying Transfer Object to fulfill their tasks. The setter also needs to send out PropertyChangeEvents (line 18).

You could add more getters and setters here. But you should use the @Transient and @NoCopy to control the bean behaviour.

The DAO Interface Class

1
2
3
4
5
6
public interface CustomerDAO extends IGeneralDAO<Long ,Customer> {
 
   /** Find by name */
   public List<Customer> findBy(String name);
 
}

The interface inherits from IGeneralDAO and requires the Key Class and the BO Interface class (line 1). Our example also defines a new method findBy(String) so that an application can retrieve customer objects by their name (line 4). However, basic search methods are already available through the super interface.

Please check out the IGeneralDAO API to learn what methods are already defined by the super interface.

The DAO Implementation Class

1
2
3
4
5
6
7
public class CustomerDaoImpl extends AbstractHibernateDAO<Long,CustomerDTO,CustomerImpl,Customer> implements CustomerDAO {
 
   public List<Customer> findBy(String name) {
      return findByCriteria(buildCriteria(Restrictions.eq("name", name)));
   }
 
}

The class inherits from AbstractHibernateDAO and requires the Key class, the DTO class, the BO Implementation class and the BO Interface class in its signature. It is the implementation of our CustomerDAO interface (line 1).

The super-class provides many useful helper methods which make it easy for you to implement a search method. Be aware that Hibernate configuration is based on Transfer Objects. Therefore, the DAO implementation must wrap the DTO in a BO Implementation class. The super-class provides such functionality and ensures that appropriate cached instances are returned when available.

The DAO Factory Interface Class

1
2
3
4
5
public interface ExampleDaoFactory extends IDaoFactory {
 
   public CustomerDAO getCustomerDAO();
 
}

The DAO Factory will make our structure complete. The interface inherits from IDaoFactory (line 1) and defines a getter for the new CustomerDAO we just implemented (line 3).

The DAO Factory Implementation Class

1
2
3
4
5
6
7
public interface ExampleDaoFactoryImpl extends AbstractDaoFactory implements ExampleDaoFactory {
 
   public CustomerDAO getCustomerDAO() {
      return getDao(CustomerDAO.class);
   }
 
}

The DAO Factory implementation derives from AbstractDaoFactory and implements our ExampleDaoFactory interface. The method implementation (line 3) will be sufficient if you rely on pure XML configuration means. Otherwise you need to instantiate and register the CustomerDaoImpl object at the constructor – or on request in the getter method as shown here:

1
2
3
4
5
6
7
8
   public CustomerDAO getCustomerDAO() {
      CustomerDAO rc = getDao(CustomerDAO.class);
      if (rc == null) {
         rc = new CustomerDaoImpl();
         registerDao(rc);
      }
      return rc;
   }

DAO Factory Configuration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<config>
   <DaoFactory class="my.package.ExampleDaoFactoryImpl" name="default">
 
      <DaoMaster class="rs.data.hibernate.HibernateDaoMaster">
         <!-- Parameters -->
         <property name="dbconfig-file">dbconfig.xml</property>
         <property name="hbmconfig-file">hibernate.cfg.xml</property>
      </DaoMaster>
 
      <!-- DAO definitions -->
      <Dao class="my.package.CustomerDAOImpl"/>
 
   </DaoFactory>
</config>

The XML defines the DAO Factory implementation class (line 3) and its configuration. You will require a HibernateDaoMaster and pass it the paths to your database (line 6) and your model definition (aka Hibernate configuration, line 7). Line 11 tells the factory what DAO it shall instantiate.

The dbconfig.xml file (database definition) looks as follows:

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
<dbconfig>
	<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
 
	<datasource class="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource">
		<property name="url">jdbc:mysql://db-host:3306/db-name</property>
		<property name="user">db-user</property>
		<property name="password">db-password</property>
        </datasource>
</dbconfig>

It is important that you define a XA DataSource as this will guarantee a correct database connection with Hibernate. Attention! Bigger applications shall use c3p0 configuration as described here.

The Hibernate configuration file hibernate.cfg.xml looks as usual but you omit any database connection property:

1
2
3
4
5
6
<hibernate-configuration>
   <session-factory>
      ...
      <mapping resource="customer.hbm.xml"/>
   <session-factory>
</hibernate-configuration>

The Bootstrap

There is only one question remaining: How do I bootstrap this structure? The answer is:

1
2
3
4
5
6
7
8
9
// Get the Model service
IOsgiModelService modelService = OsgiModelServiceImpl.getModelService();
 
// Configure the model service
XMLConfiguration pluginConfig = new XMLConfiguration("path-to-main-config.xml");
modelService.setConfiguration(pluginConfig);
 
// Load the DAO factory
ExampleDaoFactory factory = (ExampleDaoFactory)modelService.getFactory(IOsgiModelService.DEFAULT_NAME);

Line 2 will retrieve an instance of the model service which is a service to hold all factories that you define. Lines 5 and 6 actually put our main configuration file into the model service so that it is able to load our DAO factory. Finally, line 9 delivers the factory as defined in the XML file.

One Response to “Implementing Hibernate-based Data”

  1. Buy Steroids USA Says:

    […] with Bitcoins Buy American Steroids Online with Bitcoins Buy American Steroids Online with Bitcoins Buy American Steroids Online with Bitcoins Buy American Steroids Online with Bitcoins Buy American Steroids Online with Bitcoins Buy American […]

Leave a Reply