JavaBlog.fr / Java.lu DEVELOPMENT,Hibernate,Java Java/Hibernate: generate universally a unique object ID with ORM/Hibernate persistence layer

Java/Hibernate: generate universally a unique object ID with ORM/Hibernate persistence layer

In most applications, it is necessary to generate universally a unique object ID. Often, this information which is used like primary key in database, is generated via an Oracle sequencer or procedure. And its value is not really predictable. So, here, an simple solution used in an application with a layer ORM (object-relational mapping) like Hibernate:

First, it’s singleton ID generator class:

1import java.util.UUID;
2 
3public class IdGenerator {
4 
5    public static String createId() {
6        UUID uuid = java.util.UUID.randomUUID();
7        return uuid.toString();
8    }
9}

This class returns IDs with values:

1dde70a56-c67d-47cb-8c0f-5e12f9b9595f
222bf5545-ceb3-454c-8e71-b11198c16bcc
3a8d7f70f-6f3c-49af-8def-396d1f19465d

More, the previous generator is used in an abstract class whose inherits the POJO class used in the ORM layer:

1public abstract class AbstractPersistentObject {
2    private String id = IdGenerator.createId();
3    private Integer version = null;
4 
5    [...]
6}

So, the Id information is always initialized from the object’s creation.

Finally, the POJO class extends this abstract class:

1public class Document extends AbstractPersistentObject {
2 
3    private int num;
4    private int year;
5    private String type = null;
6    [...]
7}

The HBM file corresponding to the Document POJO persistence class “Document.hbm.xml”:

01<?xml version="1.0" encoding="UTF-8"?>
02<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
03<hibernate-mapping>
04    <class table="Document" name="com.ho.data.production.Document" discriminator-value="Document">
05        <id name="id" column="c_id" type="string"><generator class="assigned" /></id>
06        <discriminator column="class" type="java.lang.String"/>
07        <version name="version" column="c_version" unsaved-value="null" />
08        <property unique="true" not-null="true" column="c_num" type="int" name="num"/>
09        <property not-null="true" column="c_year" type="int" name="year"/>
10        <property column="c_type" type="java.lang.String" name="type"/>
11    </class>
12</hibernate-mapping>

To conclude with this simple post/example, here, the classes used in ORM layer in order to take into account the fact that the ID information is always initialized:

The class DAO used in ORM layer:

01@Repository("documentDao")
02@Scope("singleton")
03public class DocumentDaoHibernateImpl extends GenericDaoImpl<Document, String> implements DocumentDao {
04 
05    @Autowired
06    public DocumentDaoHibernateImpl(@Qualifier("sessionFactory") SessionFactory sessionFactory) {
07        super(sessionFactory, Document.class);
08    }
09    [...]
10}
1public interface DocumentDao extends GenericDao<Document, String> {
2 
3    [...]
4}
01import java.io.Serializable;
02import java.util.List;
03 
04public interface GenericDao<T, PK extends Serializable> {
05    PK create(T persistentObject);
06 
07    T get(PK id);
08 
09    List<T> getAll();
10 
11    void update(T persistentObject);
12     
13    void createOrUpdate(T persistentObject);
14 
15    void delete(T persistentObject);
16}

The generic component ‘GenericDaoImpl’:

001import java.io.Serializable;
002import java.util.List;
003 
004import org.hibernate.Criteria;
005import org.hibernate.Hibernate;
006import org.hibernate.SessionFactory;
007import org.hibernate.proxy.HibernateProxy;
008import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
009import org.springframework.transaction.annotation.Propagation;
010import org.springframework.transaction.annotation.Transactional;
011 
012@Transactional(propagation=Propagation.MANDATORY)
013public class GenericDaoImpl<T, PK extends Serializable> extends HibernateDaoSupport implements GenericDao<T, PK> {
014 
015 
016    //private SessionFactory sessionFactory;
017    private Class<T> type;
018 
019    public GenericDaoImpl(SessionFactory sessionFactory, Class<T> type) {
020        super.setSessionFactory(sessionFactory);
021        this.type = type;
022    }
023 
024//  public GenericDaoImpl(Class<T> type) {
025//      this.type = type;
026//  }
027 
028    @SuppressWarnings("unchecked")
029    public PK create(T o) {
030        return (PK) getSession().save(o);
031    }
032 
033    @SuppressWarnings("unchecked")
034    @Transactional(propagation=Propagation.REQUIRED, readOnly=true)
035    public T get(PK id) {
036        T value = (T) getSession().get(type, id);
037        if (value == null) {
038            return null;
039        }
040 
041        if (value instanceof HibernateProxy) {
042            Hibernate.initialize(value);
043            value = (T) ((HibernateProxy) value).getHibernateLazyInitializer().getImplementation();
044        }
045        return value;
046        //return (T) getSession().get(type, id);
047    }
048 
049    @SuppressWarnings("unchecked")
050    @Transactional(propagation=Propagation.REQUIRED, readOnly=true)
051    public List<T> getAll() {
052        Criteria crit = getSession().createCriteria(type);
053        return crit.list();
054    }
055     
056    public void createOrUpdate(T o) {
057        //Sometimes, if createOrUpdate be called with proxy then uncomment this part
058//      Class clazz = null;
059//        if (o instanceof HibernateProxy) {
060//          clazz = ((HibernateProxy) o).getHibernateLazyInitializer().getImplementation().getClass();
061//        } else {
062//          clazz = o.getClass();
063//        }
064//      if (clazz.isInstance(AbstractPersistentObject.class)) {
065//          if (((AbstractPersistentObject) o).isCreation()) {
066//              getSession().saveOrUpdate(o);
067//          } else {
068//              getSession().merge(o);
069//          }
070//      } else {
071//          throw new RuntimeException("this method support only AbstractPersistentObject");
072//      }
073         
074        if (o instanceof AbstractPersistentObject) {
075            if (((AbstractPersistentObject) o).isCreation()) {
076                getSession().saveOrUpdate(o);
077            } else {
078                getSession().merge(o);
079            }
080        } else {
081            throw new RuntimeException("this method support only AbstractPersistentObject");
082        }
083         
084         
085        //getSession().saveOrUpdate(o);
086    }
087 
088 
089    public void update(T o) {
090        getSession().update(o);
091    }
092 
093    public void delete(T o) {
094        getSession().delete(o);
095    }
096 
097//  public Session getSession() {
098//      boolean allowCreate = true;
099//      return SessionFactoryUtils.getSession(sessionFactory, allowCreate);
100//  }
101//
102//  public void setSessionFactory(SessionFactory sessionFactory) {
103//      this.sessionFactory = sessionFactory;
104//  }
105}

Best regards,

Huseyin OZVEREN

Leave a Reply

Your email address will not be published.

Time limit is exhausted. Please reload CAPTCHA.

Related Post