Search
Calendar
April 2024
S M T W T F S
« Sep    
 123456
78910111213
14151617181920
21222324252627
282930  
Your widget title
Archives

PostHeaderIcon Short Tutorial: Migration from EJB Entity to Hibernate

Case

  • let’s consider an EJB Bean AnimalBean, linked to a table JL_Animal
  • let’s have a human understandable name for the Pojo, let’s say: Animal
  • let an EJB entity have following finders:
* @ejb.finder
*   signature = "Collection findByBirthDate(java.lang.Integer birthDate)"
*   query = "SELECT OBJECT(o) FROM AnimalBean AS o WHERE o.birthDate = ?1"
*
* @ejb.finder
*   signature = "Collection findByCountryAndBirthDate(java.lang.String from,java.lang.Integer birthDate)"
*   query = "SELECT OBJECT(o) FROM AnimalBean AS o WHERE o.country = ?1 AND o.birthDate = ?2"

Create a DAO interface

In the interface AnimalDAO, we must have:

Collection findByBirthDate(Integer birthDate);
 Collection findByCountryAndBirthDate(String from,Integer birthDate);

By the way: EJB do not accept Java 5 generics, but Hibernate does. Therefore, we improve the methods signature, using generics:

Collection findByBirthDate(Integer birthDate);
Collection<Animal> findByCountryAndBirthDate(String from,Integer birthDate);

Hibernate mapping

Let’s create a Hibernate mapping file:

Primary key:

the first element of the XML file will be this:

<class name="my.personnal.package.Animal" table="JL_Animal">

if the EJB contains:

* @ejb.bean
 *   jndi-name       = "xxxxxxxxxxxxxx"
 *   local-jndi-name = "xxxxxxxxxxxxxx"
 *   description     = xxxxxxxxxxxxxxx"
 *   view-type       = "local"
 *   type            = "CMP"
 *   cmp-version     = "2.x"
 *   schema          = "AnimalBean"
 *   primkey-field   = "animalId"
 *
 * (...)
 *
 * @ejb.pk
 *   class    = "java.lang.Integer"
 *   generate = "False"
 *
 * @ejb.persistence
 *   table-name = "JL_Animal"
 *
 * @weblogic.automatic-key-generation
 *   generator-type = "XXXXXXX"
 *   generator-name = "JL_Animal_SEQ"
 *   key-cache-size = "10"

then the XML file will contain:

<id name="animalId" type="integer">
<generator>
 <param name="sequence">JL_Animal_SEQ</param>
 <param name="max_lo">10</param>
 </generator>
 </id>

The primary key may be set owing to a sequence, a class, may be assigned, etc.

Version

If the Bean contained:

* @weblogic.persistence
 *   verify-columns    = "Timestamp"
 *   optimistic-column = "OptimisticTimestamp"

or something like:

* @weblogic.cache-ref
*   cache-name                 = "primeweb.entity-cache"
 *   concountry-strategy       = "Optimistic"
 *   cache-between-transactions = "True"

then add this line to your XML file:

<version column="optimisticTimestamp" name="optimisticTimestamp" type="timestamp"/>

The version may be determined by column, name, node, access, type

Fields

For simple types, you may only write the names of the fields

<property name="country" column="countryId"/>

Attribute name is mandatory, others are not: class, column, etc.

This corresponds to an property described in the entity like this:

/**
* @ejb.persistence
 *   column-name = "countryId"
 * @ejb.interface-method
 */
 public abstract String getcountry();
 /** @ejb.interface-method */
 public abstract void setcountry(String country);

One of best Hibernate features is the ability to make joints between tables. Related keywords are many-to-one, one-to-many, one-to-one, etc. Migration from EJB to Hibernate for this kind of joints is out from this tutorial scope, we leave it at a later post.

Hibernate implementation of DAO

For CRUD methods (create/delete/update), a simple call to sessionFactory should be sufficient:

sessionFactory.getCurrentSession().persist(entity);

For more complex methods, if in the Bean you find:

* @ejb.finder
 *   signature = "Collection findByCountryAndBirthDate(java.lang.String from,java.lang.Integer birthDate)"
 *   query = "SELECT OBJECT(o) FROM AnimalBean AS o WHERE o.country = ?1 AND o.birthDate = ?2"

then in Hibernate you will have:

private static final String BY_birthDate = "FROM Animal WHERE birthDate = :birthDate order by country"

 public Collection<Animal> findByBirthDate(Integer birthDate) {
 final Query query;
 PreCondition.assertNotNull("birthDate", birthDate);
 query = getSessionFactory().getCurrentSession().createQuery(BY_birthDate);
 query.setInteger("birthDate", birthDate);
 return query.list();
 }

Misc

  • we added a “order by” clause: this is to follow a determistic behaviour on testing
  • as stated above, we used generics, even though original query did not
  • sometimes, create/update/delete methods in EJBs contain logic code. Do not forget to reproduce this logic in the Hibernate implementation
  • take care of ObjectNotFoundException and FinderException raised by EJB! Hibernate may return null objects rather than raising exceptions, this must be taken in account. A common practice is to add specific Exception in DAO, for instance AnimalNotFoundException, to be raised when the object to be returned is null.
  • In some EJBs, optimistictimestamps are not used, therefore they remain at null. This may have consequences on migrating onto Hibernate. Thus, think of setting all optimistictimestamp at current date before releasing the migration. In Oracle, the command is:
update JL_Animal set OPTIMISTICTIMESTAMP = SYSDATE where OPTIMISTICTIMESTAMP is null;

Leave a Reply