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:
3 | public class IdGenerator { |
5 | public static String createId() { |
6 | UUID uuid = java.util.UUID.randomUUID(); |
7 | return uuid.toString(); |
This class returns IDs with values:
1 | dde70a56-c67d-47cb-8c0f-5e12f9b9595f |
2 | 22bf5545-ceb3-454c-8e71-b11198c16bcc |
3 | a8d7f70f-6f3c-49af-8def-396d1f19465d |
More, the previous generator is used in an abstract class whose inherits the POJO class used in the ORM layer:
1 | public abstract class AbstractPersistentObject { |
2 | private String id = IdGenerator.createId(); |
3 | private Integer version = null ; |
So, the Id information is always initialized from the object’s creation.
Finally, the POJO class extends this abstract class:
1 | public class Document extends AbstractPersistentObject { |
5 | private String type = null ; |
The HBM file corresponding to the Document POJO persistence class “Document.hbm.xml”:
01 | <? xml version = "1.0" encoding = "UTF-8" ?> |
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" /> |
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" ) |
03 | public class DocumentDaoHibernateImpl extends GenericDaoImpl<Document, String> implements DocumentDao { |
06 | public DocumentDaoHibernateImpl( @Qualifier ( "sessionFactory" ) SessionFactory sessionFactory) { |
07 | super (sessionFactory, Document. class ); |
1 | public interface DocumentDao extends GenericDao<Document, String> { |
01 | import java.io.Serializable; |
04 | public interface GenericDao<T, PK extends Serializable> { |
05 | PK create(T persistentObject); |
11 | void update(T persistentObject); |
13 | void createOrUpdate(T persistentObject); |
15 | void delete(T persistentObject); |
The generic component ‘GenericDaoImpl’:
001 | import java.io.Serializable; |
002 | import java.util.List; |
004 | import org.hibernate.Criteria; |
005 | import org.hibernate.Hibernate; |
006 | import org.hibernate.SessionFactory; |
007 | import org.hibernate.proxy.HibernateProxy; |
008 | import org.springframework.orm.hibernate3.support.HibernateDaoSupport; |
009 | import org.springframework.transaction.annotation.Propagation; |
010 | import org.springframework.transaction.annotation.Transactional; |
012 | @Transactional (propagation=Propagation.MANDATORY) |
013 | public class GenericDaoImpl<T, PK extends Serializable> extends HibernateDaoSupport implements GenericDao<T, PK> { |
017 | private Class<T> type; |
019 | public GenericDaoImpl(SessionFactory sessionFactory, Class<T> type) { |
020 | super .setSessionFactory(sessionFactory); |
028 | @SuppressWarnings ( "unchecked" ) |
029 | public PK create(T o) { |
030 | return (PK) getSession().save(o); |
033 | @SuppressWarnings ( "unchecked" ) |
034 | @Transactional (propagation=Propagation.REQUIRED, readOnly= true ) |
035 | public T get(PK id) { |
036 | T value = (T) getSession().get(type, id); |
041 | if (value instanceof HibernateProxy) { |
042 | Hibernate.initialize(value); |
043 | value = (T) ((HibernateProxy) value).getHibernateLazyInitializer().getImplementation(); |
049 | @SuppressWarnings ( "unchecked" ) |
050 | @Transactional (propagation=Propagation.REQUIRED, readOnly= true ) |
051 | public List<T> getAll() { |
052 | Criteria crit = getSession().createCriteria(type); |
056 | public void createOrUpdate(T o) { |
074 | if (o instanceof AbstractPersistentObject) { |
075 | if (((AbstractPersistentObject) o).isCreation()) { |
076 | getSession().saveOrUpdate(o); |
078 | getSession().merge(o); |
081 | throw new RuntimeException( "this method support only AbstractPersistentObject" ); |
089 | public void update(T o) { |
090 | getSession().update(o); |
093 | public void delete(T o) { |
094 | getSession().delete(o); |
Best regards,
Huseyin OZVEREN
Related