Getting Hibernate3 to work in JDeveloper 10.1.3

Our company focuses mainly on Oracle related products. Our Java developers use JDeveloper in combination with JHeadstart to build web applications. But that doesn’t mean we’re not interested and involved in other technologies as well. We are investing lots of time into frameworks like Spring, Java Server Faces and Hibernate. In this article I will describe how I got Hibernate3 to work in Jdeveloper 10.1.3 and an Oracle 10g database.

In order to get Hibernate to work in JDeveloper, I followed these steps:

  1. Create a DataSource to use within my application
  2. Use the DataSource from within a JSP page
  3. Enable Hibernate on my project
  4. Configure Hibernate to query a table in my database using a servlet

1. Create a DataSource to use within my application
Creating a DataSource is quite simple. In JDeveloper, first open the Connections Navigator tab (select “View -> Connection Navigator” or press [CTRL-SHIFT-O]) and create a new database connection. In my case I used the OE schema on our local play-around database.
Then, select “Tools -> Embedded OC4J Server Preferences” and make sure the database connection is listed there. I chose to only use this connection in the current workspace. Since I named my database connection “oe” I have an entry called “jdev-connection-oe” in my Data Sources list.

The jdev-connection-oe database connection.

Inspecting the properties for this DataSource I notice the JNDI Name is “jdbc/oeDS”. If your connection doesn’t show up, click the [Refresh Now] button in the “Data Sources” section.

The Data Sources section with the Refresh button.

2. Use the DataSource from within a JSP page
For testing the DataSource I created a simple JSP page connecting to the DataSource and querying a table. Since I am using the OE schema I decided to query the CUSTOMERS table. First I created a new workspace in JDeveloper and created an empty project in this workspace. I then added a JSP page by right clicking the project name in the “Applications Navigator” and selecting “New…”. From the “New Gallery” window I opened “Web Tier” in the Category list and selected JSP. From the Items list I selected JSP and named it “index.jsp”. In the Tag Libraries section I selected “JSTL Core 1.1” and “JSTL SQL 1.1” and I then clicked [Finish]. This prepared my project for being a web application and made sure the needed SQL taglib is enabled on this project.
Next, I added code to query my DataSource. To do so, I selected “JSTL 1.1 SQL” in the “Components Palette” and clicked “Query”. In the “Enter Common Properties” section I entered the value “queryresults” for my variable and in the “Enter Advanced Properties” section I entered the value “jdbc/oeDS” (which is the JNDI name for my DataSource, remember?) for the DataSource. I also enetered “SELECT * FROM CUSTOMERS ORDER BY CUSTOMER_ID” as value for the “Sql” field.
In order to display the query results, I entered this code below the query statement:

<table border=1>
  <tr>
    <th>ID</th><th>First Name</th><th>Last Name</th>
  </tr>
  <c:forEach var="row" items="${queryresults.rows}">
    <tr>
      <td><c:out value="${row.CUSTOMER_ID}" /></td>
      <td><c:out value="${row.CUST_FIRST_NAME}" /></td>
      <td><c:out value="${row.CUST_LAST_NAME}" /></td>
    </tr>
  </c:forEach>
</table>

Finally, in order to make the DataSource available to the application, make sure to include this section in the web.xml file in the WEB-INF directory of the application:

<resource-ref>
  <res-ref-name>jdbc/oeDS
  <res-type>oracle.jdbc.driver.OracleDriver
  <res-auth>Container
</resource-ref>

Done! Upon running the project, I got to see this in my bowser:

The output of the JSP page.

3. Enable Hibernate on my project
Next I’d like to do the same thing using Hibernate. In order to be able to do that, I first have to prepare both my project and JDeveloper for Hibernate3.
Hibernate3 can be downloaded from this link. For preparing this article, I used Hibernate version 3.0.5. Simply download the .zip or .tar.gz file to your hard disk, unpack it and remember where you put it. One small pitfall of the JDeveloper 10.1.3 and Hibernate 3 combination, is the fact that Hibernate 3 uses slightly newer ASM and ANT jar files, which are not compatible with JDeveloper 10.1.3. Fortunately, for both there is a workaround.
In order to make the ASM jars that come with Hibernate3 work with JDeveloper 10.1.3, I went to the directory where JDeveloper was installed into. There is an asm.jar file hidden in the j2ee/home/lib directory. I replaced this jar file with the asm.jar file shipped with Hibernate3 to prevent the “java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit” error as described in this post from happening. After replacing this jar file, I restarted JDeveloper to be sure the new jar file was picked up.
Next I imported the hibernate3.jar and required third party jar files into my project. In order to do so, I right clicked my project again and selected “Project Properties…” again. In the Libraries section I clicked “Add Library…” and then “New…”. I chose a name for the new library (“Hibernate3”) and then clicked the “Add Entry…” button.
Next I browsed to the directory containing the hibernate3.jar file and selected it. After this I clicked the “Add Entry…” button again and went to the “lib” directory below the one containing the hibernate3.jar file. Here I selected “antlr-2.7.5H3.jar”, “asm.jar”, “cglib-2.1.jar”, “commons-collections-2.1.1.jar”, “commons-logging-1.0.4.jar”, “dom4j-1.6.jar” and “echache-1.1.jar”. Please note that the Hibernate documentation specifies Log4j to be an optional jar to be loaded. Doing so with JDeveloper 10.1.3 will generate an error when the OC4J server is started up, so don’t include this one. After having added the jar files, click [OK] and make sure the “Export” checkbox is checked. This will ensure the libraries will be available in the OC4J server.

Make sure the Export checkbox is checked!

4. Configure Hibernate to query a table in my database using a servlet
So, now I was able to create my Hibernate table mapping and use this in a servlet. Since I decided to query the CUSTOMERS table in the OE schema, I created a POJO called Customer.java which has private members for id, custFirstName and custLastName as well as getters and setters for these members. Next I created a configuration file called Customer.hbm.xml like this.
I right clicked the project and selected “New…”. I then expanded the “General” category and selected “XML”. In the “Items” section, I selected “XML Document”. I made sure it’s called “Customer.hbm.xml” and was put it the public_html/WEB-INF/classes directory. Since this directory didn’t exist yet, I created it. Please note this config file can be put anywhere, as long as the reference to it in the hibernate.cfg.xml file, which we will create in a moment, references it correctly. I just chose to put it there so I can keep all my Hibernate config files together. Next I made sure the contents of the “Customer.hbm.xml” file looks like this:

<?xml version="1.0"?>< !DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="nl.amis.wouter.hibernate.Customer" table="CUSTOMERS">
    <id name="id" type="int" column="Customer_Id">
      <generator class="native"/>
    </id>
    <property name="custFirstName" column="CUST_FIRST_NAME"/>
    <property name="custLastName" column="CUST_LAST_NAME"/>
  </class>
</hibernate-mapping>

Next I created the “hibernate.cfg.xml” file in the same way as the “Customer.hbm.xml” file (apart from specifying a different name of course) and made sure the contents were this:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.datasource">java:comp/env/jdbc/oeDS</property>
        <property name="show_sql">false</property>
        <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
        <property name="query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property>

        <mapping resource="Customer.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

Remember I told you there was a problem related to the versions of ANT being different between JDeveloper 10.1.3 and Hibernate3? This link tells you what is the cause of the problem. It also says to either make sure the Hibernate3 jar files are loaded before the BEA Weblogic (or in our case, the OC4J) jar files, or to use the Hibernate 2.1 query parser. Here you can find that setting the “hibernate.query.factory_class” to “org.hibernate.hql.classic.ClassicQueryTranslatorFactory” will tell Hibernate3 to use the Hibernate2.1 query parser, which solved the problem of the “ClassNotFoundException: org.hibernate.hql.ast.HqlToken” error I got. By the way, I found the link to this workaround here.

So, the last thing I had do now was to create a servlet that uses Hibernate to query my database and disply the results. Again I right clicked the project and selected “New…”. This time I expanded the “Web Tier” category and selected “Servlets”. In the “Items” section I selected “HTTP Servlet”. I named the servlet “HibernateServlet” and put it in the “nl.amis.wouter.servlets” package. I also selected the methods “doGet()” and “doPost()” to be created. I then specified no parameters to be taken into account but I did specify a name and a mapping for the servlet, which were “HibernateServlet” and “/hibernateservlet” respectively. I then clicked [Finish]. When I was done modifying the code, my servlet looked like this:

package nl.amis.wouter.servlets;

import java.util.Iterator;
import nl.amis.wouter.hibernate.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.PrintWriter;
import java.io.IOException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class HibernateServlet extends HttpServlet {
    SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();
        Query query = session.createQuery("select c from Customer as c");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.println("");
        out.println("HibernateServlet");
        out.println("");
        out.println("");
        out.println("");
        out.println("");
        out.println("");
        for (Iterator it = query.iterate(); it.hasNext();) {
            Customer c = (Customer)it.next();
            out.println("");
        }
        out.println("
IDFirst NameLast Name
" + c.getId() + "" + c.getCustFirstName() + "" + c.getCustLastName() + "
"); tx.commit(); session.close(); out.println(""); out.close(); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } }

Upon starting the servlet by selecting it in the Code Editor and hitting the [F11] key, I saw this output appear in my browser window:

Output of the Hibernate3 enabled servlet.

Yes, it looks pretty much the same. As a matter of fact, the output IS the same. So, it works!

Please note this article only goes to prove it is possible to get Hibernate3 and JDeveloper 10.1.3 work together. I know my SQL code isn’t the most effective in the world (which is the first reason for me to want to use a mapping framework like Hibernate). Besides that, I am not sure what the effect of replacing the asm.jar file in JDeveloper will do in the long run. Finally, using the Hibernate2.1 query parser rather than the Hibernate3 version may very well mean some of the new Hibernate features may not work as expected. But it’s a start and I am happy about it 🙂

31 Comments

  1. Kieran Kelly September 22, 2011
  2. Rajendra Barve January 21, 2010
  3. Alejandro Alves February 1, 2007
  4. Clark October 27, 2006
  5. Wouter van Reeven July 20, 2006
  6. Mark B. July 17, 2006
  7. Mark B. July 15, 2006
  8. Mark B. July 14, 2006
  9. Wouter van Reeven May 29, 2006
  10. hank May 24, 2006
  11. Wouter van Reeven February 23, 2006
  12. Wouter van Reeven February 23, 2006
  13. Ash February 22, 2006
  14. Ash February 16, 2006
  15. Wouter van Reeven February 16, 2006
  16. Ash February 16, 2006
  17. Wouter van Reeven February 16, 2006
  18. Ash February 16, 2006
  19. Ash February 16, 2006
  20. Wouter van Reeven January 18, 2006
  21. Alex January 17, 2006
  22. Wouter van Reeven December 23, 2005
  23. sudha December 22, 2005
  24. Wouter van Reeven October 7, 2005
  25. Eduardo October 5, 2005
  26. Ashok September 15, 2005
  27. Jordi Lopez September 2, 2005
  28. Rama Vangala August 27, 2005
  29. Wouter van Reeven August 15, 2005
  30. Shay August 13, 2005
  31. Maike Dulk August 12, 2005