Thursday, 12 March 2015

Hibernate Issue – Initial SessionFactory Creation Failed.Java.Lang.NoClassDefFoundError: Org/Dom4j/DocumentException

A common Hibernate’s error, this is caused by the missing dependency library – dom4j.
Initial SessionFactory creation failed.java.lang.NoClassDefFoundError: org/dom4j/DocumentException
Exception in thread "main" java.lang.ExceptionInInitializerError
 at com.mkyong.persistence.HibernateUtil.buildSessionFactory(HibernateUtil.java:18)
 at com.mkyong.persistence.HibernateUtil.<clinit>(HibernateUtil.java:8)
 at com.mkyong.common.App.main(App.java:17)
Caused by: java.lang.NoClassDefFoundError: org/dom4j/DocumentException
 at com.mkyong.persistence.HibernateUtil.buildSessionFactory(HibernateUtil.java:13)
 ... 2 more
Caused by: java.lang.ClassNotFoundException: org.dom4j.DocumentException
 at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
 at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
 ... 3 more

Solution

You can download the library here – http://sourceforge.net/projects/dom4j/files/dom4j/
Or
Add the dependency in Maven’s pom.xml
       <dependency>
  <groupId>dom4j</groupId>
  <artifactId>dom4j</artifactId>
  <version>1.6.1</version>
 </dependency>

Hibernate Issue – An AnnotationConfiguration Instance Is Required To Use

The Hibernate annotation is required “AnnotationConfiguration” instead of normal “Configuration()” to build the session factory.
INFO: Configuration resource: /hibernate.cfg.xml
Initial SessionFactory creation failed.org.hibernate.MappingException: 
An AnnotationConfiguration instance is required to use <mapping class="com.mkyong.common.Stock"/>
Exception in thread "main" java.lang.ExceptionInInitializerError
 at com.mkyong.persistence.HibernateUtil.buildSessionFactory(HibernateUtil.java:19)
 at com.mkyong.persistence.HibernateUtil.<clinit>(HibernateUtil.java:8)
 at com.mkyong.common.App.main(App.java:11)
Caused by: org.hibernate.MappingException: An AnnotationConfiguration instance is required to use <mapping class="com.mkyong.common.Stock"/>
 at org.hibernate.cfg.Configuration.parseMappingElement(Configuration.java:1600)
 at org.hibernate.cfg.Configuration.parseSessionFactory(Configuration.java:1555)
 at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1534)
 at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1508)
 at org.hibernate.cfg.Configuration.configure(Configuration.java:1428)
 at org.hibernate.cfg.Configuration.configure(Configuration.java:1414)
 at com.mkyong.persistence.HibernateUtil.buildSessionFactory(HibernateUtil.java:13)
 ... 2 more

Solution

1. Download the Hibernate annotation library

You can download the library from Hibernate official website
Or
Add the dependency in Maven’s pom.xml
        <!-- Hibernate annotation -->
 <dependency>
  <groupId>hibernate-annotations</groupId>
  <artifactId>hibernate-annotations</artifactId>
  <version>3.3.0.GA</version>
 </dependency>
P.S You may need to include the JBoss repository in order to download the Hibernate annotation library.
<repositories>
    <repository>
      <id>JBoss repository</id>
      <url>http://repository.jboss.com/maven2/</url>
    </repository>
  </repositories>

2. Use AnnotationConfiguration to build session factory

Normal Hibernate XML file mapping is using Configuration()
          return new Configuration().configure().buildSessionFactory();
For Hibernate annotation, you have to change it to “AnnotationConfiguration”
          return new AnnotationConfiguration().configure().buildSessionFactory();
HibernateUtil.java
A full example of “HibernateUtil.java” of using “AnnotationConfiguration” for Hibernate annotation applacation.
package com.mkyong.persistence;
 
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
 
public class HibernateUtil {
 
    private static final SessionFactory sessionFactory = buildSessionFactory();
 
    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            return new AnnotationConfiguration().configure().buildSessionFactory();
 
        }
        catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
 
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
 
    public static void shutdown() {
     // Close caches and connection pools
     getSessionFactory().close();
    }
 
}

Hibernate Issue - Org.Hibernate.AnnotationException: Unknown Id.Generator

Problem

Runing the following Hibernate’s annotation sequence generator with PostgreSQL database.
        @Id 
 @Column(name="user_id", nullable=false) 
 @GeneratedValue(strategy = GenerationType.SEQUENCE ,generator="account_user_id_seq")
 private Integer userId;
Hits the following Unknown Id.generator exception.
Caused by: org.hibernate.AnnotationException: Unknown Id.generator: account_user_id_seq
 at org.hibernate.cfg.BinderHelper.makeIdGenerator(BinderHelper.java:413)
 at org.hibernate.cfg.AnnotationBinder.bindId(AnnotationBinder.java:1795)
 at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1229)
 at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:733)
The sequence “account_user_id_seq” is created in PostgreSQL database, what caused the above exception?

Solution

When declaring the Hibernate’s annotation strategy to use “Sequences” as Id generator, try specify the @SequenceGenerator as well, as following
        @Id 
 @Column(name="user_id", nullable=false) 
 @SequenceGenerator(name="my_seq", sequenceName="account_user_id_seq")
 @GeneratedValue(strategy = GenerationType.SEQUENCE ,generator="my_seq")
 private Integer userId;

Hibernate Issue - Remember That Ordinal Parameters Are 1-Based!...

Problem

HibernateTemplate code …
getHibernateTemplate().find("from Domain d 
where d.domainName = :domainName", domainName);
When i execute the above code, i hit the following error message
java.lang.IndexOutOfBoundsException: Remember that ordinal parameters are 1-based!
 ...
 at org.hibernate.impl.AbstractQueryImpl.determineType(AbstractQueryImpl.java:397)
 at org.hibernate.impl.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:369)

Solution

I go inside and study HibernateTemplate.java file and find below code
public List find(final String queryString, final Object[] values) throws DataAccessException {
 return (List) executeWithNativeSession(new HibernateCallback() {
  public Object doInHibernate(Session session) throws HibernateException {
   Query queryObject = session.createQuery(queryString);
   prepareQuery(queryObject);
   if (values != null) {
    for (int i = 0; i < values.length; i++) {
     queryObject.setParameter(i, values[i]);
    }
   }
   return queryObject.list();
  }
 });
}
From code above, the HibernateTemplete is using 0-based instead of 1-based. Is this a spring or hibernate library problem? Since error message stated parameters need to start at 1-based. I tried some solution like change spring or hibernate library, however it’s not working…
It’s seem I’m on a wrong direction, i have to start finding solution at beginning again, first i study my own code…………!!! I cant imaging how careless i am, i made a stupid mistake on my code, this is not spring or hibernate problem, it is my syntax error.
Change from
getHibernateTemplate().find("
    from Domain d where d.domainName = :domainName", domainName);
To
getHibernateTemplate().find("
    from Domain d where d.domainName = ?", domainName);
Problem solved, code execute without error anymore.
Note
The error message generated by HibernateTemplate is really misleading !!!

Hibernate Issue - Java.Lang.ClassNotFoundException : Javassist.Util.Proxy.MethodFilter

Problem

Using Hibernate 3.6.3, but hits this javassist not found error, see below for error stacks :
Caused by: java.lang.NoClassDefFoundError: javassist/util/proxy/MethodFilter
 ...
 at org.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:77)
 ... 16 more
Caused by: java.lang.ClassNotFoundException: javassist.util.proxy.MethodFilter
 at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
 at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
 ... 21 more

Solution

javassist.jar is missing, and you can get the latest from JBoss Maven repositorty.
File : pom.xml
<project ...>
 <repositories>
  <repository>
   <id>JBoss repository</id>
   <url>http://repository.jboss.org/nexus/content/groups/public/</url>
  </repository>
 </repositories>
 
 <dependencies>
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-core</artifactId>
   <version>3.6.3.Final</version>
  </dependency>
 
  <dependency>
   <groupId>javassist</groupId>
   <artifactId>javassist</artifactId>
   <version>3.12.1.GA</version>
  </dependency>
 
 </dependencies>
</project>

Hibernate Issue – The Type AnnotationConfiguration Is Deprecated

Problem

Working with Hibernate 3.6, noticed the previous “org.hibernate.cfg.AnnotationConfiguration“, is marked as “deprecated“.
Code snippets …
import org.hibernate.cfg.AnnotationConfiguration;
//...
private static SessionFactory buildSessionFactory() {
 try {
 
  return new AnnotationConfiguration().configure().buildSessionFactory();
 
 } catch (Throwable ex) {
 
  System.err.println("Initial SessionFactory creation failed." + ex);
  throw new ExceptionInInitializerError(ex);
 }
}
The code is still working, just keep displaying the deprecated warning message, is there any replacement for “AnnotationConfiguration” ?

Solution

In Hibernate 3.6, “org.hibernate.cfg.AnnotationConfiguration” is deprecated, and all its functionality has been moved to “org.hibernate.cfg.Configuration“.
So , you can safely replace your “AnnotationConfiguration” with “Configuration” class.
Code snippets …
import org.hibernate.cfg.Configuration;
//...
private static SessionFactory buildSessionFactory() {
 try {
 
  return new Configuration().configure().buildSessionFactory();
 
 } catch (Throwable ex) {
 
  System.err.println("Initial SessionFactory creation failed." + ex);
  throw new ExceptionInInitializerError(ex);
 }
}

Hibernate Issue – Could Not Find C3P0ConnectionProvider

Problem

Configured Hibernate to use “c3p0” connection pool, but hits following warning :
//...
2011-04-25_12:18:37.190 WARN  o.h.c.ConnectionProviderFactory - 
c3p0 properties is specificed, but could not find 
 
org.hibernate.connection.C3P0ConnectionProvider from the classpath,
 these properties are going to be ignored.
2011-04-25_12:18:37.191 INFO  o.h.c.DriverManagerConnectionProvider - 
Using Hibernate built-in connection pool (not for production use!)
//...
Look like “org.hibernate.connection.C3P0ConnectionProvider” is missing?

Solution

Since Hibernate v3.3 (if not mistaken), the “C3P0ConnectionProvider” is moved to another jar file “hibernate-c3p0.jar“. You need to include it, in order to make Hibernate supports c3p0 connection pool.
You can download the “hibernate-c3p0.jar” from JBoss public repository.
File : pom.xml
<project ...>
 
 <repositories>
  <repository>
   <id>JBoss repository</id>
   <url>http://repository.jboss.org/nexus/content/groups/public/</url>
  </repository>
 </repositories>
 
 <dependencies>
 
  <!-- Hibernate c3p0 connection pool -->
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-c3p0</artifactId>
   <version>3.6.3.Final</version>
  </dependency>
 
 </dependencies>
</project>