Hi, I am using the HibernateUtil class provided by the CaveatEmperor
source code.
I have also a CustomerDAO class that with the help of the HibernateUtil
class saves,deletes or finds a customer.
I have a control class that communicates with the CustomerDAO class.
The problem is, once I save a customer object in my (GUI swing j2se) application, the control class and CustomerDAO do the job fine.
But if I want to update the customer details during the same moment
or maybe session is the right word, the details do not get updated eventough I am using the saveOrUpdate method.
(If I retrieve the object after restarting the application I can of course
update it, but no more changes can be made to it during that moment,
this is of course not the way I want to do it, restarting my application
every time!)
I might have closed a session, or maybe not, or maybe I am not using the
HibernateUtil class correctly.
Also I have added the commitTransaction method in the CustomerDAO
class for each method that needs to write data.
If I do not do that, then the data is not inserted in the database,
the source code did not include the commitTransaction method initially,
I had to add it myself, but is that where the problem may be.
I believe it is transaction, session thing , the way I use the HibernateUtil
class may be wrong.
Here below is my code.
Thanks!
Code:
public class CustomerDAO {
public CustomerDAO() {
HibernateUtil.beginTransaction();
}
// ********************************************************** //
public Customer getCustomerById(int customerId, boolean lock)
throws InfrastructureException {
Session session = HibernateUtil.getSession();
Customer customer = null;
try {
if (lock) {
customer = (Customer) session.load(Customer.class, customerId, LockMode.UPGRADE);
} else {
customer = (Customer) session.load(Customer.class, customerId);
}
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
return customer;
}
// ********************************************************** //
public Collection findAll()
throws InfrastructureException {
Collection customers;
try {
customers = HibernateUtil.getSession().createCriteria(Customer.class).list();
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
return customers;
}
// ********************************************************** //
public Collection findByExample(Customer exampleCustomer)
throws InfrastructureException {
Collection customers;
try {
Criteria crit = HibernateUtil.getSession().createCriteria(Customer.class);
customers = crit.add(Example.create(exampleCustomer)).list();
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
return customers;
}
// ********************************************************** //
public void makePersistent(Customer customer)
throws InfrastructureException {
try {
HibernateUtil.getSession().saveOrUpdate(customer);
HibernateUtil.commitTransaction();
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
}
// ********************************************************** //
public void update(Customer customer)
throws InfrastructureException {
try{
HibernateUtil.getSession().update(customer);
HibernateUtil.commitTransaction();
}
catch(HibernateException ex){
throw new InfrastructureException(ex);
}
}
// ********************************************************** //
public void makeTransient(Customer customer)
throws InfrastructureException {
try {
HibernateUtil.getSession().delete(customer);
HibernateUtil.commitTransaction();
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
}
public Customer getCustomer(String phone)
throws InfrastructureException {
Session session = HibernateUtil.getSession();
try{
Iterator iter = session.iterate("from Customer customer order by customer");
while(iter.hasNext()){
Customer customer = (Customer)iter.next();
if(customer.getPhone().equals(phone)){
return customer;
}
}
}
catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
return null;
}
}
HibernateUtil
Code:
import net.sf.hibernate.*;
import net.sf.hibernate.cfg.Configuration;
import org.apache.commons.logging.*;
import javax.naming.*;
/**
* Basic Hibernate helper class, handles SessionFactory, Session and Transaction.
* <p>
* Uses a static initializer for the initial SessionFactory creation
* and holds Session and Transactions in thread local variables. All
* exceptions are wrapped in an unchecked InfrastructureException.
*
*
*/
public class HibernateUtil {
private static Log log = LogFactory.getLog(HibernateUtil.class);
private static Configuration configuration;
private static SessionFactory sessionFactory;
private static final ThreadLocal threadSession = new ThreadLocal();
private static final ThreadLocal threadTransaction = new ThreadLocal();
private static final ThreadLocal threadInterceptor = new ThreadLocal();
// Create the initial SessionFactory from the default configuration files
static {
try {
configuration = new Configuration();
sessionFactory = configuration.configure().buildSessionFactory();
// We could also let Hibernate bind it to JNDI:
// configuration.configure().buildSessionFactory()
} catch (Throwable ex) {
// We have to catch Throwable, otherwise we will miss
// NoClassDefFoundError and other subclasses of Error
log.error("Building SessionFactory failed.", ex);
throw new ExceptionInInitializerError(ex);
}
}
/**
* Returns the SessionFactory used for this static class.
*
* @return SessionFactory
*/
public static SessionFactory getSessionFactory() {
/* Instead of a static variable, use JNDI:
SessionFactory sessions = null;
try {
Context ctx = new InitialContext();
String jndiName = "java:hibernate/HibernateFactory";
sessions = (SessionFactory)ctx.lookup(jndiName);
} catch (NamingException ex) {
throw new InfrastructureException(ex);
}
return sessions;
*/
return sessionFactory;
}
/**
* Returns the original Hibernate configuration.
*
* @return Configuration
*/
public static Configuration getConfiguration() {
return configuration;
}
/**
* Rebuild the SessionFactory with the static Configuration.
*
*/
public static void rebuildSessionFactory()
throws InfrastructureException {
synchronized(sessionFactory) {
try {
sessionFactory = getConfiguration().buildSessionFactory();
} catch (Exception ex) {
throw new InfrastructureException(ex);
}
}
}
/**
* Rebuild the SessionFactory with the given Hibernate Configuration.
*
* @param cfg
*/
public static void rebuildSessionFactory(Configuration cfg)
throws InfrastructureException {
synchronized(sessionFactory) {
try {
sessionFactory = cfg.buildSessionFactory();
configuration = cfg;
} catch (Exception ex) {
throw new InfrastructureException(ex);
}
}
}
/**
* Retrieves the current Session local to the thread.
* <p/>
* If no Session is open, opens a new Session for the running thread.
*
* @return Session
*/
public static Session getSession()
throws InfrastructureException {
Session s = (Session) threadSession.get();
try {
if (s == null) {
log.debug("Opening new Session for this thread.");
if (getInterceptor() != null) {
log.debug("Using interceptor: " + getInterceptor().getClass());
s = getSessionFactory().openSession(getInterceptor());
} else {
s = getSessionFactory().openSession();
}
threadSession.set(s);
}
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
return s;
}
/**
* Closes the Session local to the thread.
*/
public static void closeSession()
throws InfrastructureException {
try {
Session s = (Session) threadSession.get();
threadSession.set(null);
if (s != null && s.isOpen()) {
log.debug("Closing Session of this thread.");
s.close();
}
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
}
/**
* Start a new database transaction.
*/
public static void beginTransaction()
throws InfrastructureException {
Transaction tx = (Transaction) threadTransaction.get();
try {
if (tx == null) {
log.debug("Starting new database transaction in this thread.");
tx = getSession().beginTransaction();
threadTransaction.set(tx);
}
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
}
/**
* Commit the database transaction.
*/
public static void commitTransaction()
throws InfrastructureException {
Transaction tx = (Transaction) threadTransaction.get();
try {
if ( tx != null && !tx.wasCommitted()
&& !tx.wasRolledBack() ) {
log.debug("Committing database transaction of this thread.");
tx.commit();
}
threadTransaction.set(null);
} catch (HibernateException ex) {
rollbackTransaction();
throw new InfrastructureException(ex);
}
}
/**
* Commit the database transaction.
*/
public static void rollbackTransaction()
throws InfrastructureException {
Transaction tx = (Transaction) threadTransaction.get();
try {
threadTransaction.set(null);
if ( tx != null && !tx.wasCommitted() && !tx.wasRolledBack() ) {
log.debug("Tyring to rollback database transaction of this thread.");
tx.rollback();
}
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
} finally {
closeSession();
}
}
/**
* Reconnects a Hibernate Session to the current Thread.
*
* @param session The Hibernate Session to be reconnected.
*/
public static void reconnect(Session session)
throws InfrastructureException {
try {
session.reconnect();
threadSession.set(session);
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
}
/**
* Disconnect and return Session from current Thread.
*
* @return Session the disconnected Session
*/
public static Session disconnectSession()
throws InfrastructureException {
Session session = getSession();
try {
threadSession.set(null);
if (session.isConnected() && session.isOpen())
session.disconnect();
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
return session;
}
/**
* Register a Hibernate interceptor with the current thread.
* <p>
* Every Session opened is opened with this interceptor after
* registration. Has no effect if the current Session of the
* thread is already open, effective on next close()/getSession().
*/
public static void registerInterceptor(Interceptor interceptor) {
threadInterceptor.set(interceptor);
}
private static Interceptor getInterceptor() {
Interceptor interceptor =
(Interceptor) threadInterceptor.get();
return interceptor;
}
}