Friday, June 1, 2012

Converting from Hibernate hbm.xml to annotations (JPA)

I am trying to migrate my Hibernate project from mapping using the hbm.xml to the annotations using the Java Persistence API JPA.

During the generation of the mapping files, I have the hbm.xml but also the annotated POJO. Accoding to Hibernate, once we have the *.hbm.xml files and the annotations, the hbm will have the priority and will be then used by default.  In order to change this priority, we can modify the proriety hibernate.mapping.precedence from the default value hbm, class to the new value class, hbm.
So I have done this change in my src/hibernate.cfg.xml file to test it before using the persistence.xml file.

< property name="hibernate.mapping.precedence" > class < / property >

So my persistence.xml file looks like that:

< persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" >
< !-- Transaction type is jta by default for the JEE environment -- >
    < persistence-unit name="myHibernateSession" transaction-type="JTA" >
      
        < jta-data-source > java:/jdbc/myDatasource < / jta-data-source >  
              
        < properties >
            < property name="hibernate.mapping.precedence" value="class, hbm" / >
            < property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/myDB " / >
            < property name="hibernate.connection.username" value="admin" / >
            < property name="hibernate.connection.password" value="admin" / >
            < property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" / >
            < property name="hibernate.connection.driver_class" value="org.gjt.mm.mysql.Driver" / >
        < / properties >

    < / persistence-unit >
< / persistence >

While checking in the JBoss server log, I have noticed that Hibernate uses all the time the org.hibernate.cfg.HbmBinder which "Walks an XML mapping document and produces the Hibernate configuration-time metamodel".

Or when using the annotation, the binder should be the org.hibernate.cfg.AnnotationBinder. So I have
removed all my *.hbm.xml files.


When I have tested my solution, I have error telling me that "myHibernateSession not bound" so my hibernate sessionFactory is not bound and thus not working and the access to my data is impossible.
Log :
 get hibernate session
 get hibernate session factory
 myHibernateSession not bound

To initialise the context, we should change the code to  retreive the hibernate sessionfactory  from the entity manager.

EntityManagerFactory emf = Persistence.createEntityManagerFactory("myHibernateSession");
EntityManager em = emf.createEntityManager();    
Session sessionFactory = (Session)em.getDelegate();

All seems to be good now, I test my application and now its works and my session is opened except that I have this error :O
Log:
javax.persistence.PersistenceException: org.hibernate.HibernateException: The chosen transaction strategy requires access to the JTA TransactionManager

When specifying the parameter  transaction-type="RESOURCE_LOCAL", I have read that
"In a Java EE environment, if this element is not specified, the default is JTA. In a Java SE environment, if this element is not specified, the default is RESOURCE_LOCAL."

So I have set the transaction type to JTA, and the error was :

javax.persistence.PersistenceException: org.hibernate.HibernateException: The chosen transaction strategy requires access to the JTA TransactionManager

The solution was to add this property to my persistence.xml file

< property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JBossTransactionManagerLookup" / >
 
or this one if your are not using JBOSS
< property name="hibernate.transaction.manager_lookup_class" 
 value="com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup" / >
 
Yopiii, Now all is well working. 
 

Articles les plus consultés