I’ve set up a Spring project with Hibernate 3, and I’m using annotations. I’ve just implemented an import script that populates an object and saves using a session object which I’ve got from the HibernateSessionFactory.getSession() call.
My config looks like this (names & details changed to protect the innocent, etc.)
<?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">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="hbm2ddl.auto">update</property>
<property name="dialect">
org.hibernate.dialect.PostgreSQLDialect
</property>
<property name="connection.url">
jdbc:postgresql://localhost:5432/foobar
</property>
<property name="connection.username">myuser</property>
<property name="connection.password">mypass</property>
<property name="connection.driver_class">
org.postgresql.Driver
</property>
<property name="myeclipse.connection.profile">
org.postgres.Driver
</property>
<mapping class="com.mycompany.Foo" />
<mapping class="com.mycompany.Bar" />
</session-factory>
</hibernate-configuration>
As far as I understand, the hbm2ddl.auto=update config should mean my tables will be created automatically.
My HibernateSessionFactory looks like this:
package com.mycompany;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.AnnotationConfiguration;
/**
* Configures and provides access to Hibernate sessions, tied to the
* current thread of execution. Follows the Thread Local Session
* pattern, see {@link http://hibernate.org/42.html }.
*/
public class HibernateSessionFactory {
/**
* Location of hibernate.cfg.xml file.
* Location should be on the classpath as Hibernate uses
* #resourceAsStream style lookup for its configuration file.
* The default classpath location of the hibernate config file is
* in the default package. Use #setConfigFile() to update
* the location of the configuration file for the current session.
*/
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
private static Configuration configuration = new AnnotationConfiguration();
private static org.hibernate.SessionFactory sessionFactory;
private static String configFile = CONFIG_FILE_LOCATION;
static {
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
private HibernateSessionFactory() {
}
/**
* Returns the ThreadLocal Session instance. Lazy initialize
* the <code>SessionFactory</code> if needed.
*
* @return Session
* @throws HibernateException
*/
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession() : null;
threadLocal.set(session);
}
return session;
}
/**
* Rebuild hibernate session factory
*
*/
public static void rebuildSessionFactory() {
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
/**
* Close the single hibernate session instance.
*
* @throws HibernateException
*/
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close();
}
}
/**
* return session factory
*
*/
public static org.hibernate.SessionFactory getSessionFactory() {
return sessionFactory;
}
/**
* return session factory
*
* session factory will be rebuilded in the next call
*/
public static void setConfigFile(String configFile) {
HibernateSessionFactory.configFile = configFile;
sessionFactory = null;
}
/**
* return hibernate configuration
*
*/
public static Configuration getConfiguration() {
return configuration;
}
}
I’m pretty sure I’m using this code correctly, basically the logic of my code follows this:
Session session = HibernateSessionFactory.getSession();
Foo foo = new Foo();
...
session.save(foo);
So this should either save my objects or start yelling and screaming about something stupid I’ve done wrong. Nothing happens.
There is no output in the logs, the tables are still not present, and I’ve tested the connection manually and via an Eclipse plugin which uses the config directly. Even the save() calls have no effect or error.
Is this a config or logic error? Cheers.
You at least have the following problem: you don’t start and commit any transaction. Read http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#transactions-demarcation-nonmanaged for details about how you’re supposed to handle Hibernate transactions.
Note that since you’re using Spring, you should definitely use its Hibernate support, which would completely avoid the need for this HibernateSessionFactory class, and would allow you to demarcate transactions declaratively, instead of programmatically. Don’t reinvent the wheel, and read http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#orm-hibernate.