-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 
Author Message
 Post subject: [SOLVED] AnnotationConfiguration to use persistence.xml
PostPosted: Wed Jan 27, 2010 11:04 pm 
Newbie

Joined: Fri Jul 25, 2008 5:22 am
Posts: 12
Hello ...

I was wondering if anyone knows a way to use the AnnotationConfiguration class in a manner that makes it use the persistence.xml file instead of the hibernate.cfg.xml file.

I'm doing an app that does not use JBoss Seam or Struts or Spring or anything. I'm just using a servlet (pretty bare bones I know) to do this:

Code:
    private static final SessionFactory sf;

    static {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            sf = new AnnotationConfiguration().configure().
                buildSessionFactory();

        } catch (Throwable e) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + e);
            throw new ExceptionInInitializerError(e);
        }
    }


Where the servlet will later do this:

Code:
    Session session = sf.getCurrentSession();
    Transaction tx = session.beginTransaction();
    ... // some POJO creation/gathering/editing
    session.save(somePOJO);
    tx.commit();
    ... // perform some queries
    session.close();


Currently I am getting the following exception:

Code:
org.hibernate.HibernateException: /hibernate.cfg.xml not found


Of course because I don't have a hibernate.cfg.xml file. My persistence.xml file works just fine with the EntityManager. Like I say I just want to stay standard with persistence.xml so that my code is more portable. Much appreciated anyone has a suggested solution.


Last edited by Arron.Ferguson on Wed Feb 03, 2010 9:06 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Forcing AnnotationConfiguration to use persistence.xml
PostPosted: Thu Jan 28, 2010 5:31 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
If you want to use persistence.xml then you must use the JPA approach:
Code:
EntityManagerFactory emf =  Persistence.createEntityManagerFactory();
SessionFactory sf = emf.getSessionFactory();


instead to :
Code:
SessionFactory sf = new AnnotationConfiguration().configure().
                buildSessionFactory();


Top
 Profile  
 
 Post subject: Re: Forcing AnnotationConfiguration to use persistence.xml
PostPosted: Thu Jan 28, 2010 12:08 pm 
Newbie

Joined: Fri Jul 25, 2008 5:22 am
Posts: 12
pb00067 wrote:
If you want to use persistence.xml then you must use the JPA approach:
Code:
EntityManagerFactory emf =  Persistence.createEntityManagerFactory();
SessionFactory sf = emf.getSessionFactory();


instead to :
Code:
SessionFactory sf = new AnnotationConfiguration().configure().
                buildSessionFactory();


Unfortunately that removes any abilities of recognizing annotations. After scouring many forums and blogs I haven't come across any reasonable way of doing this. One way was to get the path to the application; but this is generally considered bad - especially when redeployment is due to development or on a cloud. Thus, assuming the path will always work is flawed.

My problem was that I was converting an Ant build template that I wrote for Seam-which used Facelets, RichFaces, Hibernate all within Tomcat-and therefore used a different set of configuration files.

I came across a nice little NetBeans tutorial that builds the template for Hibernate only which was really what I needed. This allows me to continue using annotations.

Anyways, thanks for the response, it is appreciated.

:)

_________________
“The Edge... there is no honest way to explain it because the only people who really know where it is are the ones who have gone over.” - Hunter S. Thompson


Top
 Profile  
 
 Post subject: Re: Forcing AnnotationConfiguration to use persistence.xml
PostPosted: Fri Jan 29, 2010 3:14 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Quote:
EntityManagerFactory emf = Persistence.createEntityManagerFactory();
Unfortunately that removes any abilities of recognizing annotations.


That's not true.
With proper classpath and autodetection set, hibernate detects annotated classes automatically.
Code:
<property name="hibernate.archive.autodetection" value="class, hbm"/>


Furthermore you can specify explicitly archives where to find annotate persistence classes with the
<jar-file>-tag
If you use absolute paths and a fixed location on filesystem then you can also avoid deployment problems


Top
 Profile  
 
 Post subject: Re: Forcing AnnotationConfiguration to use persistence.xml
PostPosted: Fri Jan 29, 2010 4:16 am 
Newbie

Joined: Fri Jul 25, 2008 5:22 am
Posts: 12
pb00067 wrote:
Quote:
EntityManagerFactory emf = Persistence.createEntityManagerFactory();
Unfortunately that removes any abilities of recognizing annotations.


That's not true.
With proper classpath and autodetection set, hibernate detects annotated classes automatically.
Code:
<property name="hibernate.archive.autodetection" value="class, hbm"/>


Furthermore you can specify explicitly archives where to find annotate persistence classes with the
<jar-file>-tag
If you use absolute paths and a fixed location on filesystem then you can also avoid deployment problems



Thanks pb00067 for your response. Define "proper classpath". Also, I'm not sure what you mean by "you can specify explicitly archives where to find annotate persistence classes with the jar-file tag". Do you mean that you can specify an entire JAR contains annotated classes for use with Hibernate? And where would this XML element go?

Lastly, the property element, does that go into the persistence.xml file?

Thanks for your attention to this thread.

Regards,

Arron

_________________
“The Edge... there is no honest way to explain it because the only people who really know where it is are the ones who have gone over.” - Hunter S. Thompson


Top
 Profile  
 
 Post subject: Re: Forcing AnnotationConfiguration to use persistence.xml
PostPosted: Fri Jan 29, 2010 5:18 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Here a sample of a persistence.xml I use:

Code:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"  version="1.0">

<persistence-unit name="bclayer">
  <jar-file>/mypath/persistentannotatedclasses.jar</jar-file>
   <properties>
     <!-- Scan for annotated classes and Hibernate mapping XML files -->
     <property name="hibernate.archive.autodetection" value="class, hbm"/>

     <property name="hibernate.connection.url"              value="jdbc:hsqldb:hsql://localhost"/>
     <property name="hibernate.connection.driver_class"     value="org.hsqldb.jdbcDriver"/>
     <property name="hibernate.connection.username"         value="sa"/>
     <property name="hibernate.connection.password"         value=""/>
     <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
   
    </properties>
</persistence-unit>
</persistence>


Top
 Profile  
 
 Post subject: Re: Forcing AnnotationConfiguration to use persistence.xml
PostPosted: Fri Jan 29, 2010 7:16 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
>>Define "proper classpath"

I mean simply, that your java classpath must also refer/contain the annotated classes.

To be more specific I made following experience:
1. For Application runtime it is enough that annotated classes are in classpath witout specifying any <jar-file>
explicitely, and AnnotationConfiguration properly finds and parses them.
(anyway specifying the <jar-file> fastens up the initialization as in this way not all classes in classpath are scanned for annotations)
2. If using hibernate ant-task hibernatetool to define the database scheme,
I was not able to make hbm2ddl find the annotated classes without specifying <jar-file> explicitely,
even if the classpath ${project.class.path} refers the annotated classes.
Code:
<hibernatetool destdir="${basedir}">
              <classpath path="${project.class.path}"/>
              <jpaconfiguration persistenceunit="bclayer"/><!-- Uses META-INF/persistence.xml -->
               <hbm2ddl
                   drop="true"
                   create="true"
                   export="true"
                   outputfilename="bootstrap-ddl.sql"
                   delimiter=";"
                   format="true"/>
           </hibernatetool>


Top
 Profile  
 
 Post subject: Re: Forcing AnnotationConfiguration to use persistence.xml
PostPosted: Wed Feb 03, 2010 9:04 pm 
Newbie

Joined: Fri Jul 25, 2008 5:22 am
Posts: 12
pb00067,

Sorry I didn't respond sooner. I had a bunch of things I had to do. Additionally, I had a very difficult time getting HSQLDB or Derby to work correctly and decided to use MySQL. These are for quick templates and so there is an appeal to have an embedded DB for a template of course.

Tomcat also presents some challenges where it doesn't seem to like the DB driver anywhere but in it's lib directory (doesn't work when it's in the web app lib sub directory). Anyways, I did get it working with the persistence.xml like you said and with annotations. I thank you for your help in this and suggestions to persevere. Thanks for your time, definitely. :)

In the end, my persistence.xml became:

Code:
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <!-- Adapted from: https://www.hibernate.org/114.html, Hibernate Web site -->
  <persistence-unit name="fbh" transaction-type="RESOURCE_LOCAL">
    <properties>

      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
      <property name="hibernate.default_schema" value="fbh" />
      <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
      <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/fbh" />
      <property name="hibernate.archive.autodetection" value="class, hbm"/>
      <property name="hibernate.connection.username" value="root"/>
      <property name="hibernate.connection.password" value="root"/>

      <!-- Use the C3P0 connection pool. -->
      <property name="c3p0.min_size" value="3" />
      <property name="c3p0.max_size" value="5" />
      <property name="c3p0.timeout" value="1800" />

      <!-- Disable second-level cache. -->
      <property name="cache.provider_class" value="org.hibernate.cache.NoCacheProvider" />
      <property name="cache.use_query_cache" value="false" />
      <property name="cache.use_minimal_puts" value="false" />
      <property name="max_fetch_depth" value="3" />

      <!-- Print SQL to stdout. -->
      <property name="show_sql" value="true" />
      <property name="format_sql" value="true" />

      <!-- Drop and then re-create schema on SessionFactory build, for testing. -->
      <property name="hibernate.hbm2ddl.auto" value="create" />

      <!-- Bind the getCurrentSession() method to the thread. -->
      <property name="current_session_context_class" value="thread" />

    </properties>
  </persistence-unit>
</persistence>


My annotated class was:

Code:
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.validator.Length;
import org.hibernate.validator.Min;
import org.hibernate.validator.Max;
import org.hibernate.validator.NotEmpty;

@Entity
@Table(name="user")
public class User  implements Serializable {

    private static final long serialVersionUID = 1881413500711441951L;

    public User() {
        firstName = "test";
        lastName = "data";
    }

    public User(String first, String last) {
        firstName = first;
        lastName = last;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", nullable = false, updatable=false)
    private long id;

    @Column(name = "lastName", nullable = false, unique = false)
    private String lastName;

    @Column(name = "firstName", nullable = false, unique = false)
    private String firstName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String toString() {
        return firstName + " " + lastName;
    }

}


And my servlet (for simple testing) became:

Code:
import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import javax.servlet.ServletContext;
import javax.servlet.ServletConfig;
import javax.servlet.ServletOutputStream;
import javax.servlet.UnavailableException;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import org.apache.log4j.Logger;

public class Loader extends HttpServlet {

    private static final String PERSISTENCE_UNIT = "fbh";

    private static Logger logger = Logger.getLogger(Loader.class);

    private static EntityManager em = null;

    static {
        // get entity manager via factory
        EntityManagerFactory entityManagerFactory =
            Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);
        em = entityManagerFactory.createEntityManager();
    }

    public void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
        // https://www.hibernate.org/42.html
        // http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html_single/
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        try {
            em.merge(new User());
            tx.commit();
        } catch (Exception e) {
            logger.error("APP PERSISTING ERROR: " + e.getMessage());
            tx.rollback();
        } finally {
            //logger.info("APP CLOSING ENTITY MANAGER.");
            //em.close();
        }

        ServletOutputStream out = res.getOutputStream();
        out.println("no exceptions? Good. :)");
    }


    public void doPost(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
        doGet(req, res);
    }

}


I post the above in the hopes it may be usable to others who come across configuration issues when approaching Hibernate without say a managed persistence manager. I'll mark this as "SOLVED".

_________________
“The Edge... there is no honest way to explain it because the only people who really know where it is are the ones who have gone over.” - Hunter S. Thompson


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.