Hibernate

07
Jan

Using element in Hibernate mappings

Posted by eugene as Hibernate

Element is used for mapping the collection of primitive and composite types when there’s no sense to make a separate entity.

Let’s suppose we have the ITEM table where the information about the product is stored and the ITEM_SIZE table where the information about the product sizes is stored.

The structure of the ITEM table:

  • ID – unique product identifier
  • NAME – product name
  • any fields describing the other product properties

ITEM_SIZE table structure:

  • ITEM_ID – foreign key on the ITEM table
  • SIZE – product size

We’ll create the item entity with the described properties above and the collection of tbe product sizes for the ITEM table, and we’ll do mapping for it:

public class Item 
{     
	private Integer id;
	private String name;
	private Set<Integer> sizes;
 
	// other fields, accessors 
 
}

The corresponding mapping for the Item entity:

<hibernate-mapping>
     <class name="Item" table="ITEM">
		<id name="id" type="int">
			<column name="ID" />
			<generator class="identity" />
		</id>
 
		<property name="name" type="string" column="NAME"/>
 
		<set name="sizes" table="ITEM_SIZE">
			<key column="ITEM_ID" />
			<element column="size" type="int" />
		</set>
	</class>
</hibernate-mapping>

We’re interested in the sizes property mapping.

The set element is used for the mapping of this property. The name property specifies the name of the Item entity, the table property specifies the table name.

The key element specifies the foreign key in the ITEM_SIZE table on the ITEM table. The column property specifies the column name.

Element specifies the column which data will be placed into the collection and the type of the data. The column property specifies the column name with the data, the type field – data type located in the column. The data type can be as embedded so and user.

In the next article I’ll show how to do mapping with the help of element when the Java enum element must be the collection element.

05
Jan

Using the join element in Hibernate mappings

Posted by eugene as Hibernate

With the help of the join element you can perform the property mapping of one class on the columns of several tables, the relation between them is one-to-one.

For example:

<class name=&quot;Person&quot; table=&quot;PERSON&quot;>
    <id name=&quot;id&quot; column=&quot;PERSON_ID&quot;>...</id>
    <join table=&quot;ADDRESS&quot;>
  <key column=&quot;ADDRESS_ID&quot;/>
<property name=&quot;address&quot;/>
<property name=&quot;zip&quot;/>
<property name=&quot;country&quot;/>  </join> </class>

The join element contains the following properties:

  • table – table name
  • schema – redefines schema name specified in the root Hibernate-mapping element
  • catalog – redefines catalogue name specified in the root Hibernate-mapping element
  • fetch – specifies the way of data export. By default join, i.e. for data exporting inner join will be used if the join element is defined in the current class or in the parent class. If the join element is defined in descendant (in the subclass element), then outer join will be applied for data exporting. If the select value is specified in the fetch property, then if the result line is the subclass of this class, the additional request will be used for the subclass data exporting. Inner join will be still used to join the elements defined in the class or its parent.
  • inverse – if inverse = true, then when updating/inserting the corresponding class properties, the records will be updated/added into the appropriate tables
  • optional – if optional = true, then the record will be added to the related table only if at least one property is not null in the class
30
Sep

The example of using of Hibernate as JPA Provider in conjunction with the Spring Framework

Posted by eugene as Hibernate, Spring Framework

It’s no secret that Hibernate is the “de facto” standard in the ORM-world. At the same time the production “de jure” standard is JPA – it’s also difficult to argue. Moreover, starting with the 3.6.* version Hibernate fully supports JPA standard (of different versions) and it means that there is a possibility to develop on the basis of production standard, not refussing from the favourite instrument. Nevertheless there are few compact and light examples for understanding in the network which illustrate this possibility, especially when it’s about the conjunction with Spring Framework. The article will be devoted exactly to it (to conjunction of Spring + Hibernate as JPA).

Introduction

As I’ve written above there are not so many examples, most often these will be the examples of work of Spring + Hibernate, or Spring + JPA, or Hibernate as JPA provider, etc.

The most simple and available description of using Hibernate JPA you’ll find right in distributive {HIBERNATE_HOME}/documentation/quickstart/en-US/html/hibernate-gsg-tutorial-jpa.html (the exact example is located here:{HIBERNATE_HOME}/project/documentation/src/main/docbook/quickstart/tutorials/entitymanager/). Since in my article it’s taken as a basis and it’s extremely desirable by the time you need these lines to read you have already acknowledged this example.

[FYI:]SpringSource has a separate project which supplements the opportunities of the basic Spring ORM and focused on the support of JPA – Spring Data JPA: http://static.springsource.org/spring-data/data-jpa/docs/1.1.0.RC1/reference/html/

We’ll concentrate on the conjunction variant of Spring Framework + JPA where Hibernate is represented in the role of JPA realization. Consequently we’ll need the last (at the moment of writing the article) versions of Spring Framework 3.1 and Hibernate 4.0.1.

Background

Download the source code examples (http://it.vaclav.kiev.ua/wp-content/uploads/2012/02/spring-jpa-hib-example.zip), deploy the archive and import the project into Eclipse (or any other IDE up to you). Then open the {spring-jpa-hib-example}/lib/readme.liblist.txt file and having learnt the list of necessary libraries, add them into {spring-jpa-hib-example}/lib/. Except of the several libraries you’ll find them in the Spring and Hibernate libraries respectively.

The additional libraries which you’ll need for work with the example:

For the ease of demonstration we’ll use a slight “in-memory” database variant, namely HSQLDB. Please note that while guys from JBoss like H2, their colleagues from SpringSource prefer HSQLDB for the same purposes. In general, these databases are interchangeable in most cases but we’ll focus on HSQLDB as it’s much easier to configure in the context of Spring Framework.

So, all infrastructure issues are acknowledged – the sources are present, all the libraries are loaded and available for using, you can get started studying the example.

Studying the spring-jpa-hib-example project

As I’ve already written above, the example which is as the basis of it is supplied with Hibernate 4.0.1 in which the org.hibernate.tutorial.em.Event class is used as @Entity. I hope that you’ve already acknowledged with it. Otherwise – it’s time ot do it now! Moreover, we’ll not stop on it for details – this is POLO annotated accordingly.

Let’s review the modified by me persistence.xml:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">
 
    <persistence-unit name="org.hibernate.tutorial.jpa">
        <description>
            Persistence unit for the Spring JPA tutorial with Hibernate using as JPA provider
        </description>
 
        <!-- <class>org.hibernate.tutorial.em.Event</class> -->
 
        <properties>
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="create" />
        </properties>
 
    </persistence-unit>
 
</persistence>

As you can see this is the standard persistence.xml according to JPA v.2.0 in which there’s practically nothing except some lines which parameterize Hibernate. Even org.hibernate.tutorial.em.Event is commented out. Why this is done you’ll understand below. Special interest in this file you’ll find in persistence-unit – recall it as you’ll need it further in order to configure one of the Spring beans. Let’s review it:

application-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd">
 
    <context:annotation-config />
 
    <context:component-scan base-package="org.hibernate.tutorial.em" />
 
    <jdbc:embedded-database id="dataSource">
    </jdbc:embedded-database>
 
    <bean id="lcemf"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="loadTimeWeaver">
            <bean
                class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
        </property>
        <property name="dataSource" ref="dataSource"></property>
        <property name="persistenceUnitName" value="org.hibernate.tutorial.jpa" />
        <property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>
    </bean>
 
    <bean id="eventDao" class="foo.bar.dao.EventDaoImpl" />
</beans>

Let’s review it in parts putting down trivial things:

<context:component-scan base-package="org.hibernate.tutorial.em" />

This configuration fragment will allow Spring, in conjunction with Hibernate, to find the @Entity class itself. If you remember we’ve commented its declaration from persistence.xml.

<jdbc:embedded-database id="dataSource">
</jdbc:embedded-database>

And you’ve probably haven’t coped with this block despite the fact it appeared quite long time ago in Spring, the special attention it got in the last framework versions. This tag will allow you to automatically initialize the so-called “embedded database” where HSQLDB / H2 / DERBY can be used as that. Most of all HSQLDB is preferred in SpringSource but you can quickly enough go to any of it (how to do it? see chapter 13.8 Embedded database support, Spring Reference v.3.1). I’ll only add that this solution is not only used in production! It is designated for enlightment of prototypes creation and testing which we’ll use. After completion the “context rise” you’ll get not only ready “dataSource” beanbut the raised database in memory, fully ready for work.

<bean id="lcemf"
    class="org.springframework.orm.jpa.с">
    ...
    <property name="dataSource" ref="dataSource"></property>
    <property name="persistenceUnitName" value="org.hibernate.tutorial.jpa" />
    <property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>
</bean>

And in this configuration block the magic of work with Hibernate is hidden as with the JPA provider in Spring. Not long time ago Spring represented set of XXXTemplate classes for simplifying work with different ORM, but starting from v.3.0 this practice has stopped the JpaTemplate class is already deprecated. Instead of it, there’re used several variants of EntityManagerFactoryBeans in the third string. We’ll use the most powerful of them, i.e. LocalContainerEntityManagerFactoryBean. As you can see from the context we transmit dataSource into it, persistenceUnitName and the class which implements the PersistenceProvider interface, in the case with the fourth Hibernate this is HibernatePersistence (Why haven’t guys from JBoss called it HibernatePersistenceProvider is still the puzzle for me, obviously they get some extra satisfaction to puzzle their users).

In the same time, in the Spring context we’re raising implementation of our dao: foo.bar.dao.EventDao, we’ll continue work with it literally in several seconds:

public interface EventDao {
 
    public abstract Collection<Event> loadEvents();
 
    public abstract void persistEvent(Event event);
 
}

Please find the implementation of this interface in the foo.bar.dao package. A little secret is also hidden in it which is not quite enough transparently represented in the Spring documentation.

private EntityManagerFactory emf;
 
@PersistenceUnit
public void setEntityManagerFactory(EntityManagerFactory emf) {
    this.emf = emf;
}

If you followed the train of thought attentively then you should have found that the EntityManagerFactory bean type in context hasn’t raised and in fact it couldn’t simply appear. Nevertheless we’ve created the LocalContainerEntityManagerFactoryBean instance and its conjunction with the @PersistenceUnit annotation allows Spring to get EntityManagerFactory and to implement its injection into our DAO.

All the further work with Hibernate from the Spring Framework environment is now done transparently, as with the JPA realization:

In order to make sure in the example efficiency, find the {spring-jpa-hib-example/test} / foo.bar.dao.EventDaoImplTest class and run it as a JUnit-test (required to use JUnit v.4.*).

@Test
public void testBasicUsage() {
 
    EventDao eventDao = this.context.getBean(EventDaoImpl.class);
    Collection<Event> events = eventDao.loadEvents();
    log.info("Events count: " + events.size());
    log.info(events);
 
    // checking that there are no any events in fresh db schema
    assertEquals(eventCnt, events.size());
 
    // create and persist new event
    eventDao.persistEvent(new Event( "Our very first event!", new Date() ));
    eventCnt++;
 
    events = eventDao.loadEvents();
    log.info("Events count: " + events.size());
    log.info(events);
 
    // checking that there is only one event that has been created recently
    assertEquals(eventCnt, events.size());
}

If the test completed successfully, then it means you’ve got raised Hibernate as the JPA provider in context of Spring.

In the following editions I’ll get you acquainted with not less interesting Spring Framework opportunities.

28
Sep

The Hibernate Dynamic SQL Cache project

Posted by eugene as Hibernate

Description

This project is successfully being used in several projects by myself and it showed a good efficiency. The reason for creation of the project was the inefficient cache mechanism in Hibernate, at least the developers openly write about this in documentation.

  • HQL-cache and also cache of entity-objects collections will be reset during every data update, at least in one of the tables which are present in the query. During very often table updating the use of such sort of caches leads to 0.
  • SQL-cache holds only result of the first query call in the memory and is not reset.
  • That is why we’ve got an idea of the dynamically updating cache. The result of the query is updated when performing either INSERT or DELETE of the object in the database. In order to use the given solution it’s needed to amend a bit the approach for the query construction, and also for using of different collections in entity-objects.

    • The query must return only object id. Due to the id you can easily download the object from cache. (That’s why you will get two calls to the cache what is always quicker than query execution to the database).
    • The query must be only via the invariable object fields.
    • Instead of using the collections in entity-object you should use the corresponding SQL query with the dynamic update.

    Absolutely any cache provider can be used (Infinispan, Hazelcast, EHCache …)

    The project is published under Apache License 2.0

    Example of using

    Spring is used for clarity of the example, although the project doesn’t depend on it, any other container can be used.

    Hibernate configuration. It is important to note the use of its own hibernate.cache.query_cache_factory where the whole logics of cache update management is performed:

    <session-factory>
     
          ...
    <property name="hibernate.cache.query_cache_factory">com.corundumstudio.hibernate.dsc.DynamicQueryCacheFactory</property>
    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.infinispan.InfinispanRegionFactory</property>
    <property name="hibernate.cache.use_second_level_cache">true</property>
    <property name="hibernate.cache.use_query_cache">true</property>
     
          ...
     
    </session-factory>

    Let’s register which will track the main operations by all ‘entities’.

    @Configuration
    public class QueryCacheListenerConfig {
     
        @Bean
        public QueryCacheEntityListener createCacheListener() {
                return new QueryCacheEntityListener();
        }
     
        @PostConstruct
        protected void init() {
                EventListenerRegistry registry = sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class);
                registry.getEventListenerGroup(EventType.POST_UPDATE).appendListener(createCacheListener());
                registry.getEventListenerGroup(EventType.POST_INSERT).appendListener(createCacheListener());
                registry.getEventListenerGroup(EventType.POST_DELETE).appendListener(createCacheListener());
        }
     
    }

    The example of DAO-service. com.corundumstudio.hibernate.dsc.CacheCallback – is the callback by means of which it will serve the “insert” and “delete” operations on the object (in this example, SimpleEntity), so that the results of the query will be always “fresh”.

    @Service
    public class SimpleEntityDao {
     
        private final String queryRegionName = "SimpleEntity_Query";
        private final String query = "SELECT id FROM SimpleEntity WHERE phone = :phone";
     
        @Autowired
        private QueryCacheEntityListener queryListener;
        @Autowired
        private SessionFactory sessionFactory;
     
        @PostConstruct
        protected void init() {
     
            // cache callback через который будет обслуживать операции
            // "insert" или "delete" на entity, чтобы результаты запроса были всегда "свежими"
     
         CacheCallback<SimpleEntity> handler = new CacheCallback<SimpleEntity>() {
     
          @Override
          protected void onInsertOrDelete(InsertOrDeleteCommand command,
            SimpleEntity object) {
           command.setParameter("phone", object.getPhone());
           command.setUniqueResult(object.getId());
          }
     
         };
         queryCacheEntityListener.register(SimpleEntity.class, queryRegionName, handler);
        }
     
        @Transactional
        public SimpleEntity getEntityByPhone(String phone) {
                Session session = sessionFactory.getCurrentSession();
                SQLQuery sqlQuery = session.createSQLQuery(query);
                sqlQuery.addScalar("id", LongType.INSTANCE);
                sqlQuery.setCacheable(true);
                sqlQuery.setCacheRegion(cacheRegionName);
                sqlQuery.setParameter("phone", phone);
                Long idResult = (Long) sqlQuery.uniqueResult();
                return session.get(SimpleEntity.class, idResult);
        }
     
        ...
     
        create, delete methods...
     
    }

    Now when you call SimpleEntityDao.getEntityByPhone, at the first time the request to the database will be performed. The subsequent calls of the method will return a value from the cache, and if the SimpleEntity object with the desired phone value will be added to the database, it will also appear as a result of this request. And conversely, if the object with such ‘phone’ value will be removed, then the result of the query will return null.

    If the result of the query returns the list of the objects, then in this case while deletion/creation of the object its id will be removed/added in the list.

17
Jun

Overview of new features of Hibernate 3.5 and JPA 2.0

Posted by eugene as Hibernate

Java Persistency API (JPA) 2.0 is also known as JSR-317 was released recently (December 10, 2009) and until the last week the only ORM which fully implements the specification was EclipseLink. This is a great framework which is most likely due to the reviews online, works faster than Hibernate. However, last week Hibernate 3.5 appeared, it fully implements the JPA 2.0 specification. In this article I will briefly tell you about the new possibilities of JPA 2.0 and Hibernate 3.5.

Here are a few major innovations:

  • orphanRemoval option;
  • ElementCollection annotation;
  • CollectionTable annotation.

Connection of Hibernate 3.5 to project

We will connect Hibernate to the project, as always, with the help of Maven 2. To make it work, we need to connect the Jboss repository:

<repository>
	<id>JBoss-Maven-Repository</id>
	<name>JBoss Maven Repository</name>
	<url>http://repository.jboss.org/maven2</url>
</repository>

Now you need to connect all the necessary dependencies:

<properties>
	<hibernate-core-version>3.5.0-Final</hibernate-core-version>
</properties>
...
<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-core</artifactId>
	<version>${hibernate-core-version}</version>
</dependency>
<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-annotations</artifactId>
	<version>${hibernate-core-version}</version>
</dependency>
<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-entitymanager</artifactId>
	<version>${hibernate-core-version}</version>
</dependency>
<dependency>
	<groupId>javassist</groupId>
	<artifactId>javassist</artifactId>
	<version>3.9.0.GA</version>
</dependency>
<dependency>
	<groupId>org.apache.derby</groupId>
	<artifactId>derbyclient</artifactId>
	<version>10.5.3.0_1</version>
</dependency>
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-jdk14</artifactId>
	<version>1.5.8</version>
</dependency>

Here I also connected the Apache Derby JDBC-driver, since I use it for testing.
As a result, you should have such a dependency tree:

I use Hibernate 3.5 in the JSF-project, so you can also see the JSF dependencies on the picture. You can just not pay attention to them.

The Hibernate 3.5 documentation says that the Hibernate kernel is supplied with the Hibernate annotations and Entity Manager, however, after downloading the dependencies with Maven I noticed that the classes which are responsible for the work of annotations and Entity Manager in Core are absent. After some dancing with a tambourine, it was found that when pulling the dependencies from the JBoss Maven repository, these packages are really missing in the kernel, but if you download the hibernate-distribution-3.5.0-Final-dist.zip zip-file from the site of JBoss (more precisely, from SourceForge), then the annotations packets and ejb are really present in Core. That’s why I added the Hibernate Annotations and Hibernate Entity Manager dependencies to POM.

As it turned out, this is due to the fact that these projects are now live in one SVN-project and they have the same release cycle, and hence the version of all these libraries is identical. That’s why I carried the Hibernate library version to pom.xml into properties.

Standard Properties

In the earlier specifications of JPA (up to 2.0) there were not specified any standardized names for the properties in persistence.xml, so each vendor of the JPA implementation had to determine the names of properties. A small set of standard properties is defined in JPA 2.0. Now, when you configure persistence.xml you can be use as the names of the provider properties of implementation (in this case, Hibernate), so and the standardized names.

They look like this:

1. javax.persistence.jdbc.driver (In Hibernate: hibernate.connection.driver_class)
2. javax.persistence.jdbc.user (In Hibernate: hibernate.connection.username)
3. javax.persistence.jdbc.password (In Hibernate: hibernate.connection.password)
4. javax.persistence.jdbc.url (In Hibernate: hibernate.connection.url)

I think there is nothing necessary to explain as the property names speak for themselves.

Here is my persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0">
<persistence-unit name="topcodeCorePersistenceUnit" transaction-type="RESOURCE_LOCAL">
		<class>com.scriptkiddieblog.example.entity.User</class>
		<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/scriptkiddie_db" />
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="root" />
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
		</properties>
	</persistence-unit>
</persistence>

New features and annotations mapping

There are several new annotations in JPA 2.0.

Removing of orphans by using the orfanRemoval attribute

Orphan is an object whose parent object was deleted. There were no hibernate DELETE_ORPHAN equivalent in cascade type in the previous version of JPA. In JPA 2.0 this behavior (removing of orphans) can be defined using the orphanRemoval attribute of ManyToOne and OneToMany annotations. The specification defines two different scenarios of the behavior of orphanRemoval:

  • If the target entity was detached from the entity-owner collection (one-to-many) or null is assigned to the link, then it (the target entity) will be removed from the database during the execution of flush.
  • If the parent entity has been removed, the target entity will also be deleted. In other words, if orphanRemoval = true, then there is no sense to set cascade = REMOVE as the cascade deletion will occur as a result of applying the orphanRemoval = true rule.

Here is the example of annotation:

	@OneToMany(mappedBy = "customer", cascade = CascadeType.PERSIST, fetch = FetchType.LAZY, orphanRemoval = true)
	@BatchSize(size = 100)
	private Set<Order> orders = new HashSet<Order>();

Mapping the collection of items with the help of the ElementCollection annotation

Another one innovation in JPA 2.0 is the equivalent to the CollectionOfElements annotation in Hibernate: the @ElementCollection annotation. With the help of this annotation you can map the collection of simple types or embedded (embeddable) objects. Here is an example of a simple mapping:

public class Customer {
	....
	@ElementCollection
	private Collection<String> hobbies = new HashSet<String>();

Here the collection of lines is mapped as the hobbies attribute to the Customer entity. Since we did not specify any mapping parameters, the following will occur:

  • 1.The table name will be “customer_hobbies”
  • 2.The table will consist of two columns: “customer_id” – the client ID, which has a hobby and “hobbies” — the hobby value. The line will be created for each item in the table.

By default, the column name for the embedded-data is generated from the embedded-class attribute names or the name of the collection (in our case, hobbies) for simple types. This can be changed noting the property with the built-in class type with the @AttributeOverride or @Column annotations for simple types:

public class Customer {
	....
	@ElementCollection
	@Column(name = "HOBBY_DATA")
	private Collection<String> hobbies = new HashSet<String>();

Set up a table name, you can use the new annotation @CollectionTable:

public class Customer {
	....
	@ElementCollection
	@Column(name="HOBBY_NAME")
	@CollectionTable(name="HOBBIES", joinColumns=@JoinColumn(name="CUSTID"))
	private Collection<String> hobbies = new HashSet<String>();

And as for embedded types:

 
	@ElementCollection
	@CollectionTable(name = "CUST_ADDITIONAL_ADDRS")
	private List<Address> additionalAddresses = new ArrayList<Address>();

That’s all for today.

17
Jun

How to befriend Hibernate with Spring and to provide the transaction management via @nnotations

Posted by eugene as Hibernate, Spring Framework

How to befriend Hibernate with Spring and to provide the transaction management via @nnotations

The large and complex task completed at work, and you’d like to digress a bit before the resolution of the next one and to share something with you, dear readers. Today’s post will be the series like “ones for the kids.” Let’s talk about a bunch of Spring-Hibernate, the DAO layer and dynamic transaction management.

SpringFramework is quite complicated and interesting thing. In particular, it includes the org.springframework.orm.hibernate3 package, which provides the interaction between SpringFramework and Hibernate ORM.

Let’s create a simple console application (not to bother with defining servlets and other overhead’s), which writes something into the database.

Accordingly, first of all we’ll define the entity with which we work. Let’s call it casually: MyEntity.

The code essentially looks like this:

package com.scriptkiddieblog.example.entity;
 
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.hibernate.annotations.GenericGenerator;
 
@Entity
public class MyEntity implements Serializable {
 
	private static final long serialVersionUID = 382157955767771714L;
 
	@Id
	@Column(name = "uuid")
	@GeneratedValue(generator = "system-uuid")
	@GenericGenerator(name = "system-uuid", strategy = "uuid")
	private String id;
 
	@Column(name = "name")
	private String name;
 
	public MyEntity() {
	}
 
	public MyEntity(String id, String name) {
		this.id = id;
		this.name = name;
	}
 
	public String getId() {
		return id;
	}
 
	public void setId(String id) {
		this.id = id;
	}
 
	public String getName() {
		return name;
	}
 
	public void setName(String name) {
		this.name = name;
	}
}

I’ll remind you that the @Entity, @Id, etc. annotations are related to JPA and replace Hibernate-mapping.

We won’t work with the entity directly but through DAO. Using of DAO is one of the established patterns of work with SpringFramework. Having defined the bean that implements DAO you can easily inject it into the beans that implement the business logic of the application, and thus completely separate the business logic from data manipulation. Our DAO will be implemented via the following interface:

package com.scriptkiddieblog.example.dao;
 
import com.scriptkiddieblog.example.entity.MyEntity;
 
public interface IEntityDao {
 
	public void save(MyEntity entity);
}

For the example, we’ll define a single method – save which will retain the entity into the database. DAO implementation is rather primitive:

package com.scriptkiddieblog.example.dao;
 
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.scriptkiddieblog.example.entity.MyEntity;
 
public class EntityDao extends HibernateDaoSupport implements IEntityDao {
 
	public void save(MyEntity entity) {
		getHibernateTemplate().save(entity);
	}
}

We inherit from the HibernateDaoSupport class which encapsulates the work with the Hibernate Session, and Hibernate Session Factory gives us a simple API to interact with Hibernate. I recommend an article that explains how to properly organize the DAO layer in your application.

Now let’s go to the classes which will implement the business logic. In our case, the business logic will be simple – we’ll just save the entity.

ImyEntityService interface:
 
package com.scriptkiddieblog.example.services;
 
import com.scriptkiddieblog.example.entity.MyEntity;
 
public interface IMyEntityService {
 
	public void saveEntity(MyEntity entity);
}
</pre
Implementation — MyEntityService class:
<pre lang="Java">
package com.scriptkiddieblog.example.services;
 
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.scriptkiddieblog.example.dao.IEntityDao;
import com.scriptkiddieblog.example.entity.MyEntity;
 
@Transactional(readOnly = true)
public class MyEntityService implements IMyEntityService {
 
	private IEntityDao dao;
 
	public void setDao(IEntityDao dao) {
		this.dao = dao;
	}
 
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
	public void saveEntity(MyEntity entity) {
		dao.save(entity);
	}
}

This class is the most interesting thing in our program. We need to wrap the saveEntity method in the transaction. There is the @Transactional annotation for this purpose to which you can annotate a method or a class. The behavior of the transaction is set by the parameters of this annotation. The main parameter is readOnly which points to the possibility or impossibility of modifying the state of the database and propagation which sets the strategy for the transaction (not to create a transaction, create new, join to the existing one, etc.). In addition to these parameters you can specify a timeout, the isolation level, classes and types of exceptions where it’s both required and not to do rollback.

More information about the parameters and their values can be found in the official guide for SpringFramework.

Actually, now we have to consider the configuration of Spring-context which will be stored in the applicationContext.xml file. The file will be considered in parts, in small portions. First of all, let’s create the “fish” of the file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
 
</beans>

Pay attention! It is important to register all namespaces and the path to the schemes correctly, otherwise the configuration will simply not be parsed.

So first, let’s add the necessary configuration files into the context, in this case – jdbc.properties where we will store the settings for connecting to DBMS.
The SpringFramework class contains the org.springframework.beans.factory.config.PropertyPlaceholderConfigurer class for the work with the configuration files. The layout will be as follows:

	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="jdbc.properties" />
	</bean>

Then you should determine the data source – the bridge between DBMS and Hibernate. I prefer to use this wonderful apache.commons.dbcp library for this.

	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
	</bean>

Once identified the source of the data, it’s time to describe the factory that will build the Hibernate-sessions.

There is the org.springframework.orm.hibernate3.LocalSessionFactoryBean class for it. We’ll describe this bean as follows:

	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:/hibernate.cfg.xml" />
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
			</props>
		</property>
	</bean>

All specific settings of Hibernate will be stored in the hibernate.cfg.xml file, the dialect – in the jdbc.properties file. Note that since we define the mapping by annotations, then the org.hibernate.cfg.AnnotationConfiguration class should work with such configuration.

We are connected to the database and the Hibernate-session is created. It’s time to point the application that it needs to dynamically manage the transaction. What is meant by “dynamically manage transactions?” This means that we do not need to write code that creates/closes/rolls back the transaction and to place it wherever you need. We need only to pass the HibernateTransactionManager class some rules of creation/completion of the transactions, and the rest it will take upon itself.

It’s clear that all this stuff works through AOP. The rule is a correspondence between the method and type of the transaction being created. This means that when we enter into the method (just before the start of implementation of the method code) – you need to create a transaction, and before leaving the method (after implementation of the the last statement of the method instruction) – commit the transaction. Well, and additionally you can describe due to which types of exceptions the transaction should be rolled back.

There are two basic ways of defining the rules: using of the Spring AOP notation in the Spring xml-configs, and using of annotations in Java-code. Each method has its advantages and disadvantages, but that’s the topic of another article. We’ll consider how to manage transactions using the annotations.

To manage a transaction in Spring there is a namespace tx where is defined, in particular, the tx:annotation-driven directive including the mechanism for transaction management via annotations. You can read about the parameters of this directive in section 9.5.6. of the document.

Let’s define the transaction manager as follows:

	<tx:annotation-driven transaction-manager="txManager" />
	<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
	</bean>

What remains to be determined are beans for the DAO layer and the business logic layer:

	<bean id="entityDAO" class="com.scriptkiddieblog.example.dao.EntityDao">
<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	<bean id="entityService" class="com.scriptkiddieblog.example.services.MyEntityService">
<property name="dao" ref="entityDAO" />
	</bean>

Finally I’ll give the example of the Main class code which runs the application:

package com.scriptkiddieblog.example;
 
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.scriptkiddieblog.example.entity.MyEntity;
import com.scriptkiddieblog.example.services.IMyEntityService;
 
public class Main {
 
	public static void main(String[] args) {
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		IMyEntityService service = (IMyEntityService) ctx.getBean("entityService");
		MyEntity entity = new MyEntity();
		entity.setName("Pavel");
		service.saveEntity(entity);
	}
}

The code is not complicated. First, we load the application context, then we get tge required bean from the context (in this case – “entityService”. Well, and then we use the bean according to the intended purpose — by means of it, save the entity to the database.

Actually, I think that the configuration via annotations is simpler than xml, and it’s even easier to read. In general, the interaction of beans could be also configured the bean with the help of annotations, Spring allows this for quite long time. On the topic of configuring Spring-beans through annotations, please read the articles on habrahabr: this and this.

Now you know how to connect DBMS and Hibernate to SpringFramework, to prpvide the dynamic transaction management, to describe the DAO layer and to connect DAO to the business logic. In fact, we have created the “fish” of the application and now we can indefinitely increase its functionality.

UPD 23.02.2011: Source code of the example (Maven-Project, GitHub).