Feb 21 2008
Hibernate with Guice – Part II

Welcome back to Part II about using Hibernate with Guice. If you just stepped in, i recommend first to read Part I here.
Part II – Adding Guice to the Hibernate-Application
This application uses Guice’s Dependency Injection to create the HibernateConnection-instance and the OrdersDAO-instance. You can see that HibernateUtil don’t need STATICs anymore. Access to HibernateUtil is wrapped through a HibernateConnection which is created in a ConnectionProvider as a Singleton. Providers are acting as Factories in creating and returning Objects.
Ready for action?
Create a new Project “HibernateConnectionWithGuice“, add the Hibernate, MySql and Guice JARs to it and create the following files:
OrdersController.java
package eu.jdevelop.hibernateconnectionwithguice.controller;
import com.google.inject.Inject;
import eu.jdevelop.hibernateconnectionwithguice.dao.impl.OrdersDAO;
/**
* This class is used to retrieve the one and only instance of
* OrdersDAO (it is a Singleton). We are using Guice to inject a
* OrdersDAO-instance into our controller.
*
* @author Siegfried Bolz
*/
public class OrdersController {
private OrdersDAO dao;
@Inject
public void setOrdersDAO(OrdersDAO dao) {
this.dao = dao;
}
public OrdersDAO getOrdersDAO() {
return dao;
}
} // .EOF
HibernateConnection.java
package eu.jdevelop.hibernateconnectionwithguice.dao.impl;
import eu.jdevelop.hibernateconnectionwithguice.dao.IConnection;
import eu.jdevelop.hibernateconnectionwithguice.util.HibernateUtil;
import org.hibernate.Session;
/**
* Wrapper-class for OrdersDAO (and all other DAO's).
* If you want to use an other HibernateUtil, just change the
* ConnectionProvider.class -Binding in GuiceModule or create
* other Provider- and Connection classes.
*
* @author Siegfried Bolz
*/
public class HibernateConnection implements IConnection<session>{
private HibernateUtil hibernateUtil;
public HibernateConnection(HibernateUtil hibernateUtil) {
this.hibernateUtil = hibernateUtil;
}
public void connect() {
hibernateUtil.Configure(true);
hibernateUtil.beginTransaction();
}
public void disConnect() {
hibernateUtil.closeSessionFactory();
}
public Session getSession() {
return hibernateUtil.getSession();
}
public void rollbackTransaction() {
hibernateUtil.rollbackTransaction();
}
public void commitTransaction() {
hibernateUtil.commitTransaction();
}
public void closeSession() {
hibernateUtil.closeSession();
}
} // .EOF
OrdersDAO.java
package eu.jdevelop.hibernateconnectionwithguice.dao.impl;
import com.google.inject.Singleton;
import eu.jdevelop.hibernateconnectionwithguice.dao.IConnection;
import eu.jdevelop.hibernateconnectionwithguice.dao.IGenericDAO;
import eu.jdevelop.hibernateconnectionwithguice.exceptions.InfrastructureException;
import eu.jdevelop.hibernateconnectionwithguice.model.*;
import java.util.Collection;
import org.hibernate.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* DAO for Table "orders". Running as a Singleton.
*
* @author Siegfried Bolz
*/
@Singleton
public class OrdersDAO implements IGenericDAO<orders> {
private int counter=0; // remove if not needed.
private Log logger = LogFactory.getLog(OrdersDAO.class);
private HibernateConnection connection;
public void makePersistent(Orders orders) throws InfrastructureException {
/**
* You can see here if "ordersController2" has successfully used
* the OrdersDAO-Singleton or created a new OrdersDAO-instance.
* Remove if not needed.
*/
logger.info("****** Access to OrderDAO: " + ++counter);
try {
Session session = (Session) this.getConnection().getSession();
session.save(orders);
} catch (HibernateException ex) {
this.getConnection().rollbackTransaction();
logger.error("Exception in OrdersDAO.makePersistent().", ex);
throw new InfrastructureException(ex);
}
}
public void makePersistentUpdate(Orders orders) throws InfrastructureException {
try {
Session session = (Session) this.getConnection().getSession();
session.update(orders);
} catch (HibernateException ex) {
this.getConnection().rollbackTransaction();
logger.error("Exception in OrdersDAO.makePersistentUpdate().", ex);
throw new InfrastructureException(ex);
}
}
public void makeTransient(Orders orders) throws InfrastructureException {
try {
Session session = (Session) this.getConnection().getSession();
session.delete(orders);
} catch (HibernateException ex) {
this.getConnection().rollbackTransaction();
logger.error("Exception in OrdersDAO.makeTransient(). Rollback activated.", ex);
throw new InfrastructureException(ex);
}
}
/**
* Search for all Orders-Entities in Database.
*
* @return Collection
* @throws eu.jdevelop.hibernateconnectionwithguice.exceptions.InfrastructureException
*/
public Collection findAll() throws InfrastructureException {
Collection collections;
try {
Session session = (Session) this.getConnection().getSession();
collections = session.createCriteria(Orders.class).list();
this.getConnection().commitTransaction();
} catch (HibernateException ex) {
logger.error("Exception in OrdersDAO.findAll().", ex);
throw new InfrastructureException(ex);
} finally {
this.getConnection().closeSession();
}
return collections;
}
/**
* Set HibernateConnection (Wrapper for HibernateUtil)
*
* @param connection
* @throws eu.jdevelop.hibernateconnectionwithguice.exceptions.InfrastructureException
*/
public void setConnection(IConnection connection) throws InfrastructureException {
this.connection = (HibernateConnection) connection;
}
/**
* Use this method to gain access to the Hibernate-Wrapper.
*
* @return
* @throws eu.jdevelop.hibernateconnectionwithguice.exceptions.InfrastructureException
*/
public IConnection getConnection() throws InfrastructureException {
return this.connection;
}
} // .EOF
IConnection.java
package eu.jdevelop.hibernateconnectionwithguice.dao;
/**
* Interface for creating Database-Connection-Wrappers.
*
* @author Siegfried Bolz
*/
public interface IConnection<t> {
public void connect();
public void disConnect();
public T getSession();
public void rollbackTransaction();
public void commitTransaction();
public void closeSession();
} // .EOF
IGenericDAO.java
package eu.jdevelop.hibernateconnectionwithguice.dao;
import eu.jdevelop.hibernateconnectionwithguice.exceptions.InfrastructureException;
/**
* Interface of the Generic DAO. Use this to create DAO-Implementations
* for the models.
*
* @author Siegfried Bolz
*/
public interface IGenericDAO<t> {
public void setConnection(IConnection connection)
throws InfrastructureException;
public IConnection getConnection()
throws InfrastructureException;
public void makePersistent(T var)
throws InfrastructureException;
public void makePersistentUpdate(T var)
throws InfrastructureException;
public void makeTransient(T var)
throws InfrastructureException;
} // .EOF
InfrastructureException.java
package eu.jdevelop.hibernateconnectionwithguice.exceptions;
/**
* This exception is used to mark (fatal) failures in infrastructure and system code.
*
* @author Siegfried Bolz
*/
public class InfrastructureException extends RuntimeException {
public InfrastructureException() {
}
public InfrastructureException(String message) {
super(message);
}
public InfrastructureException(String message, Throwable cause) {
super(message, cause);
}
public InfrastructureException(Throwable cause) {
super(cause);
}
} // .EOF
Article.java
package eu.jdevelop.hibernateconnectionwithguice.model;
import java.io.Serializable;
/**
* Simple Article-Model.
*
* @author Siegfried Bolz
*/
public class Article implements Serializable{
private Long id;
private String name;
private double price;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
} // .EOF
Customer.java
package eu.jdevelop.hibernateconnectionwithguice.model;
import java.io.Serializable;
/**
* Simple Customer-Model.
*
* @author Siegfried Bolz
*/
public class Customer implements Serializable{
private Long id;
private String name;
private String street;
private String city;
private String postcode;
private String phone;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getPostcode() {
return postcode;
}
public void setPostcode(String postcode) {
this.postcode = postcode;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
} // .EOF
Orders.java
package eu.jdevelop.hibernateconnectionwithguice.model;
import java.io.Serializable;
import java.util.Date;
/**
* Simple Orders-Model.
*
* @author Siegfried Bolz
*/
public class Orders implements Serializable {
private Long id;
private Customer customer;
private Article article;
private int amount;
private Date orderDate;
private double sum;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public Article getArticle() {
return article;
}
public void setArticle(Article article) {
this.article = article;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(Date orderDate) {
this.orderDate = orderDate;
}
public double getSum() {
return sum;
}
public void setSum(double sum) {
this.sum = sum;
}
} // .EOF
The following three *.hbm.xml -files are in the package: eu.jdevelop.hibernateconnectionwithguice.model
Article.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="eu.jdevelop.hibernateconnectionwithguice.model.Article" table="article">
<id name="id" column="id">
<generator class="native" />
</id>
<property name="name" column="name" not-null="true" />
<property name="price" column="price" not-null="true" />
</class>
</hibernate-mapping>
Customer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="eu.jdevelop.hibernateconnectionwithguice.model.Customer" table="customer">
<id name="id" column="id">
<generator class="native" />
</id>
<property name="name" column="name" not-null="true" />
<property name="street" column="street" not-null="true" />
<property name="city" column="city" not-null="true" />
<property name="postcode" column="postcode" not-null="true" />
<property name="phone" column="phone" not-null="true" />
</class>
</hibernate-mapping>
Orders.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="eu.jdevelop.hibernateconnectionwithguice.model.Orders" table="orders">
<id name="id" column="id">
<generator class="native" />
</id>
<property name="amount" column="amount" not-null="true" />
<property name="orderDate" column="orderDate" not-null="true" />
<property name="sum" column="sum" not-null="true" />
<many-to-one name="customer" class="eu.jdevelop.hibernateconnectionwithguice.model.Customer" column="customerId" cascade="save-update"/>
<many-to-one name="article" class="eu.jdevelop.hibernateconnectionwithguice.model.Article" column="articleId" cascade="save-update"/>
</class>
</hibernate-mapping>
GuiceModule.java
package eu.jdevelop.hibernateconnectionwithguice.modules;
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
import eu.jdevelop.hibernateconnectionwithguice.dao.impl.HibernateConnection;
import eu.jdevelop.hibernateconnectionwithguice.provider.ConnectionProvider;
import static java.lang.annotation.ElementType.*;
/**
* Configuration-class for guice. Here are the bindings defined.
*
* @author Siegfried Bolz
*/
public class GuiceModule extends AbstractModule{
@Override
protected void configure() {
/**
* Without the Scopes.SINGLETON, each time wenn you call
* HibernateConnection connection = injector.getInstance(HibernateConnection.class);
* a new Instance of HibernateConnection (with the included HibernateUtil) will be created.
*/
bind(HibernateConnection.class).toProvider(ConnectionProvider.class).in(Scopes.SINGLETON);
}
} // .EOF
ConnectionProvider.java
package eu.jdevelop.hibernateconnectionwithguice.provider;
import com.google.inject.Provider;
import static java.lang.annotation.ElementType.*;
import com.google.inject.Inject;
import eu.jdevelop.hibernateconnectionwithguice.dao.impl.HibernateConnection;
import eu.jdevelop.hibernateconnectionwithguice.util.HibernateUtil;
/**
* A simple Provider class that conforms to Guice Provider that creates and
* return HibernateConnection objects. Guice automatically injects a brand new
* HibernateUtil-instance (as singleton, defined in class GuiceModule).
*
* @author Siegfried Bolz
*/
public class ConnectionProvider implements Provider<hibernateConnection>{
private final HibernateUtil hibernateUtil;
@Inject
ConnectionProvider(HibernateUtil hibernateUtil) {
this.hibernateUtil = hibernateUtil;
}
public HibernateConnection get() {
HibernateConnection connection = new HibernateConnection(hibernateUtil);
return connection;
}
} // .EOF
HibernateUtil.java
package eu.jdevelop.hibernateconnectionwithguice.util;
import eu.jdevelop.hibernateconnectionwithguice.exceptions.InfrastructureException;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.naming.*;
/**
* Large Hibernate helper class, handles SessionFactory, Session and Transaction.
*
* Uses a initializer for the initial SessionFactory creation
* and holds Session and Transactions in thread local variables. All
* exceptions are wrapped in an unchecked InfrastructureException.
*
* @version 1.2
* @author Siegfried Bolz (www.jdevelop.eu)
*/
public class HibernateUtil {
/** Logger. */
private Log log = LogFactory.getLog(HibernateUtil.class);
/** configuration. */
private Configuration configuration;
/** Session Factory */
private SessionFactory sessionFactory;
/** JNDI name of sessionfactory. */
private final String JNDI_SESSIONFACTORY = "java:hibernate/HibernateFactory";
/** If running unit tests set to true. */
private boolean offlineMode = true;
/** threadlocal. */
private final ThreadLocal threadSession = new ThreadLocal();
/** threadlocal. */
private final ThreadLocal threadTransaction = new ThreadLocal();
/** threadlocal. */
private final ThreadLocal threadInterceptor = new ThreadLocal();
/** Interceptor class */
private final String INTERCEPTOR_CLASS = "hibernate.util.interceptor_class";
/**
* Create the initial SessionFactory from hibernate.xml.cfg or JNDI).
* #### Use this Function to initialize Hibernate! ####
*
* @param offlineMode true=hibernate.cfg.xml , false=JNDI
*/
public void Configure(boolean offlineMode) {
log.debug("HibernateUtil.Configure() - Trying to initialize Hibernate.");
try {
// Use hibernate.cfg.xml (true) or JNDI (false)
setOfflineMode(offlineMode);
sessionFactory = getSessionFactory();
} catch (Throwable x) {
// We have to catch Throwable, otherwise we will miss
// NoClassDefFoundError and other subclasses of Error
log.error("HibernateUtil.Configure() - Building SessionFactory failed.", x);
throw new ExceptionInInitializerError(x);
}
}
/**
* Use hibernate.cfg.xml (true) to create sessionfactory or bound
* sessionfactory to JNDI (false)
*/
public void setOfflineMode(boolean mode)
{
if (mode==true)
log.debug("HibernateUtil.setOfflineMode() - Setting mode to hibernate.cfg.xml .");
else
log.debug("HibernateUtil.setOfflineMode() - Setting mode to JNDI.");
offlineMode = mode;
}
/**
* Returns the SessionFactory used for this class. If offlineMode has
* been set then we use hibernate.cfg.xml to create sessionfactory, if not
* then we use sessionfactory bound to JNDI.
*
* @return SessionFactory
*/
public SessionFactory getSessionFactory() {
if (sessionFactory == null) {
if (offlineMode == true) {
log.debug("HibernateUtil.getSessionFactory() - Using hibernate.cfg.xml to create a SessionFactory");
try {
configuration = new Configuration();
sessionFactory = configuration.configure().buildSessionFactory();
} catch (HibernateException x) {
throw new InfrastructureException("HibernateUtil.getSessionFactory() - Error creating SessionFactory with hibernate.cfg.xml .",x);
}
} else {
log.debug("HibernateUtil.getSessionFactory() - Using JDNI to create a SessionFactory");
try {
Context ctx = new InitialContext();
sessionFactory = (SessionFactory) ctx.lookup(JNDI_SESSIONFACTORY);
} catch (NamingException x) {
throw new InfrastructureException("HibernateUtil.getSessionFactory() - Error creating JNDI-SessionFactory.",x);
}
}
}
if (sessionFactory == null) {
throw new IllegalStateException("HibernateUtil.getSessionFactory() - SessionFactory not available.");
}
return sessionFactory;
}
/**
* Sets the given SessionFactory.
*
* @param sessionFactory
*/
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
/**
* Returns the original Hibernate configuration.
*
* @return Configuration
*/
public Configuration getConfiguration() {
return configuration;
}
/**
* Rebuild the SessionFactory with the Configuration.
*
*/
public void rebuildSessionFactory() throws InfrastructureException {
log.debug("HibernateUtil.rebuildSessionFactory() - Rebuilding the SessionFactory with the Configuration.");
synchronized (sessionFactory) {
try {
sessionFactory = getConfiguration().buildSessionFactory();
} catch (Exception x) {
throw new InfrastructureException("HibernateUtil.rebuildSessionFactory() - Error rebuilding SessionFactory with the Configuration",x);
}
}
}
/**
* Rebuild the SessionFactory with the given Hibernate Configuration.
*
* @param cfg
*/
public void rebuildSessionFactory(Configuration cfg) throws InfrastructureException {
log.debug("HibernateUtil.rebuildSessionFactory() - Rebuilding the SessionFactory from the given Hibernate Configuration.");
synchronized (sessionFactory) {
try {
if (sessionFactory != null && !sessionFactory.isClosed())
sessionFactory.close();
sessionFactory = cfg.buildSessionFactory();
configuration = cfg;
} catch (Exception x) {
throw new InfrastructureException("HibernateUtil.rebuildSessionFactory() - Error rebuilding the SessionFactory with the given Hibernate Configuration",x);
}
}
}
/**
* Destroy this SessionFactory and release all resources (caches, connection
* pools, etc).
*
* @author Siegfried Bolz
* @param cfg
*/
public void closeSessionFactory() throws InfrastructureException {
synchronized (sessionFactory) {
try {
log.debug("HibernateUtil.closeSessionFactory() - Destroy the current SessionFactory.");
sessionFactory.close();
// Clear variables
configuration = null;
sessionFactory = null;
} catch (Exception x) {
throw new InfrastructureException("HibernateUtil.closeSessionFactory() - Error destroying the current SessionFactory",x);
}
}
}
/**
* 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 Session getSession() throws InfrastructureException {
Session s = (Session) threadSession.get();
try {
if (s == null) {
log.debug("HibernateUtil.getSession() - Opening new Session for this thread.");
if (getInterceptor() != null) {
log.debug("HibernateUtil.getSession() - Using interceptor: "+ getInterceptor().getClass());
s = getSessionFactory().openSession(getInterceptor());
} else {
s = getSessionFactory().openSession();
}
threadSession.set(s);
}
} catch (HibernateException x) {
throw new InfrastructureException("HibernateUtil.getSession() - Error retrieving/creating a session.",x);
}
return s;
}
/**
* Closes the Session local to the thread.
*/
public void closeSession() throws InfrastructureException {
try {
Session s = (Session) threadSession.get();
threadSession.set(null);
if (s != null && s.isOpen()) {
log.debug("HibernateUtil.closeSession() - Closing Session of this thread.");
s.close();
}
} catch (HibernateException x) {
throw new InfrastructureException("HibernateUtil.closeSession() - Error closing the session.",x);
}
}
/**
* Start a new database transaction.
*/
public void beginTransaction() throws InfrastructureException {
Transaction tx = (Transaction) threadTransaction.get();
try {
if (tx == null) {
log.debug("HibernateUtil.beginTransaction() - Starting new database transaction in this thread.");
tx = getSession().beginTransaction();
threadTransaction.set(tx);
}
} catch (HibernateException x) {
throw new InfrastructureException("HibernateUtil.beginTransaction() - Error starting a new database transaction.",x);
}
}
/**
* Commit the database transaction.
*/
public void commitTransaction() throws InfrastructureException {
Transaction tx = (Transaction) threadTransaction.get();
try {
if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
log.debug("HibernateUtil.commitTransaction() - Committing database transaction of this thread.");
tx.commit();
}
threadTransaction.set(null);
} catch (HibernateException x) {
rollbackTransaction();
throw new InfrastructureException("HibernateUtil.commitTransaction() - Error commiting the database transaction.",x);
}
}
/**
* Rollback the database transaction.
*/
public void rollbackTransaction() throws InfrastructureException {
Transaction tx = (Transaction) threadTransaction.get();
try {
threadTransaction.set(null);
if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
log.debug("HibernateUtil.rollbackTransaction() - Tyring to rollback database transaction of this thread.");
tx.rollback();
}
} catch (HibernateException x) {
throw new InfrastructureException("HibernateUtil.rollbackTransaction() - Error rolling back the database transaction.",x);
} finally {
closeSession();
}
}
/**
* Reconnects a Hibernate Session to the current Thread.
*
* @param session The Hibernate Session to be reconnected.
*/
public void reconnect(Session session) throws InfrastructureException {
log.debug("HibernateUtil.reconnect() - Reconnecting Hibernate Session to the current Thread.");
try {
session.reconnect(session.connection());
threadSession.set(session);
} catch (HibernateException x) {
throw new InfrastructureException("HibernateUtil.reconnect() - Error reconnectin to the given session.",x);
}
}
/**
* Disconnect and return Session from current Thread.
*
* @return Session the disconnected Session
*/
public Session disconnectSession() throws InfrastructureException {
log.debug("HibernateUtil.disconnectSession() - Disconnecting Session from current Thread.");
Session session = getSession();
try {
threadSession.set(null);
if (session.isConnected() && session.isOpen()) {
session.disconnect();
}
} catch (HibernateException x) {
throw new InfrastructureException("HibernateUtil.disconnectSession() - Error disconnecting session from current thread.",x);
}
return session;
}
/**
* Register a Hibernate interceptor with the current thread.
*
* 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 void registerInterceptor(Interceptor interceptor) {
threadInterceptor.set(interceptor);
}
/**
* Get Hibernate interceptor.
*
* @return Interceptor
*/
private Interceptor getInterceptor() {
Interceptor interceptor = (Interceptor) threadInterceptor.get();
return interceptor;
}
/**
* Resets global interceptor to default state.
*/
public void resetInterceptor() {
log.debug("HibernateUtil.resetInterceptor() - Resetting global interceptor to configuration setting");
setInterceptor(configuration, null);
}
/**
* Either sets the given interceptor on the configuration or looks it up
* from configuration if null.
*/
private void setInterceptor(Configuration configuration, Interceptor interceptor) {
String interceptorName = configuration.getProperty(INTERCEPTOR_CLASS);
if (interceptor == null && interceptorName != null) {
try {
log.debug("HibernateUtil.setInterceptor() - Configuring interceptor.");
Class interceptorClass = HibernateUtil.class.getClassLoader().loadClass(interceptorName);
interceptor = (Interceptor) interceptorClass.newInstance();
} catch (Exception x) {
throw new RuntimeException("HibernateUtil.setInterceptor() - Error, could not configure interceptor: " + interceptorName, x);
}
}
if (interceptor != null) {
configuration.setInterceptor(interceptor);
} else {
configuration.setInterceptor(EmptyInterceptor.INSTANCE);
}
}
} // .EOF
Main.java
package eu.jdevelop.hibernateconnectionwithguice;
import eu.jdevelop.hibernateconnectionwithguice.dao.impl.*;
import eu.jdevelop.hibernateconnectionwithguice.model.*;
import com.google.inject.*;
import eu.jdevelop.hibernateconnectionwithguice.controller.OrdersController;
import eu.jdevelop.hibernateconnectionwithguice.modules.GuiceModule;
import java.util.Date;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Hibernate with Guice - Part II
*
* This is a simple Hibernate-Application which was extended with
* Guice functionality. To see this Application without Guice,
* just visit Part I.
*
* @author Siegfried Bolz (www.jdevelop.eu)
*/
public class Main {
private static Log logger = LogFactory.getLog(Main.class);
public static void main(String[] args) {
/**
* There are our bindings defined.
*/
GuiceModule module = new GuiceModule();
/**
* The creation of this injector is something that you would do once, probably upon
* application startup. The injector is initiated with our bindings.
*/
Injector injector = Guice.createInjector(new Module[]{module});
/**
* The injector injects our controller instance with its dependencies.
* Our OrdersDAO-instance will be now created.
*/
OrdersController ordersController = new OrdersController();
injector.injectMembers(ordersController);
/**
* Here we use the Factory to create a HibernateConnection (with its
* HibernateUtil-reference) instance.
*/
HibernateConnection connection = injector.getInstance(HibernateConnection.class);
connection.connect(); // initialize HibernateUtil
/**
* Retrieve the previously created instance.
*/
OrdersDAO dao = ordersController.getOrdersDAO();
/**
* Link the HibernateConnection-instance to the OrderDAO-instance.
* OrderDAO needs this reference to the HibernateUtil.
*/
dao.setConnection(connection);
/**
* Create entities
*/
Article article1 = new Article();
article1.setName("iPhone");
article1.setPrice(399.99);
Customer customer1 = new Customer();
customer1.setCity("Munich");
customer1.setName("Siegfried Bolz");
customer1.setPhone("555123123");
customer1.setPostcode("80222");
customer1.setStreet("Mainstreet 12");
Orders order1 = new Orders();
order1.setAmount(1);
order1.setOrderDate(new Date());
order1.setSum(article1.getPrice() * order1.getAmount());
order1.setArticle(article1);
order1.setCustomer(customer1);
/**
* Let OrderDAO handle the persistence.
*/
dao.makePersistent(order1);
/**
* Commit transaction.
*/
connection.commitTransaction();
/**
* Close Hibernate SessionFactory and all sessions.
*/
connection.disConnect();
/**
* ********************* now look if guice handles singleton correctly *************************
*/
/**
* Create a new OrdersController but retrieve the same old OrdersDAO-Instance
* as in line 44 (singleton).
*/
OrdersController ordersController2 = new OrdersController();
injector.injectMembers(ordersController2);
OrdersDAO dao2 = ordersController2.getOrdersDAO();
/**
* New database-input.
*/
Article article2 = new Article();
article2.setName("MacBook Air");
article2.setPrice(1799.99);
Customer customer2 = new Customer();
customer2.setCity("Kempten");
customer2.setName("Max Mustermann");
customer2.setPhone("01714465435");
customer2.setPostcode("87435");
customer2.setStreet("Sunset Blv. 6");
Orders order2 = new Orders();
order2.setAmount(2);
order2.setOrderDate(new Date());
order2.setSum(article2.getPrice() * order2.getAmount());
order2.setArticle(article2);
order2.setCustomer(customer2);
/**
* Retrieves the same old HibernateConnection-Instance as in line 52 (singleton!).
*/
HibernateConnection connection2 = injector.getInstance(HibernateConnection.class);
connection2.connect(); // reconnect to database
dao2.setConnection(connection2);
dao2.makePersistent(order2);
connection2.commitTransaction(); // write in database
/**
* get number of orders in database
*/
logger.info("****** Number of orders in database: " + dao.findAll().size());
connection2.disConnect(); // finish connection
}
} // .EOF
The last two files are located at the root of your source-directory.
hibernate.cfg.xml
Take a closer look at this configuration file, if you experience connection-problems to your database.
<?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>
<!-- Settings for a local MySQL database. -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateguicetest</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<!-- Print SQL to stdout. -->
<property name="show_sql">true</property>
<!-- Mapping files. -->
<mapping resource="eu/jdevelop/hibernateconnectionwithguice/model/Article.hbm.xml" />
<mapping resource="eu/jdevelop/hibernateconnectionwithguice/model/Customer.hbm.xml" />
<mapping resource="eu/jdevelop/hibernateconnectionwithguice/model/Orders.hbm.xml" />
</session-factory>
</hibernate-configuration>
log4j.properties
log4j.rootLogger=INFO, A1 log4j.appender.A1=org.apache.log4j.ConsoleAppender log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x -%m%n
The file structure looks now like this (here from NetBeans 6):
![]()
If you build and run the application, two entites with its sub-entities will be added to your database:
![]()
Downloads
NetBeans 6 Project Part I: download
NetBeans 6 Project Part II: download
Libaries: download
Further informations
Open existing NetBeans 6 Projects: http://blog.jdevelop.eu/?p=29
Google Guice: http://code.google.com/p/google-guice/
Hibernate: http://www.hibernate.org/
Now you have seen how Guice works and how you can create loose couplings with Dependency Injection. This was my first attempt working with Guice, so i think there are many points which can be improved.
It was hard work to create this examples and writing this blog. If you have any suggestions, feel free to write a comment.
Writing 220-601 is compulsory after 70-291 if you are planning to attempt 646-204 followed by 70-649 or 70-620 and the future goal is 642-901.
5 responses so far
You should check out warp-persist, it is a tiny library (60K) that integrates Hibernate, JPA and db4objects with Guice applications:
http://www.wideplay.com
It also provides a powerful query abstraction that lets you get rid of Dao code:
http://www.wideplay.com/dynamicfinders
Warp-persist is heavily tested and provides lightweight, guice-style integration.
Thank you for this Information, Warp-Persist looks very great! :-) I will try to use it with this project and create a new blog-entry when i am finished.
[...] http://blog.jdevelop.eu/?p=26Session; /** * Wrapper-class for OrdersDAO (and all other DAO’s). * If you want to use an other HibernateUtil, just change the * ConnectionProvider.class -Binding in GuiceModule or create * other Provider- and Connection classes. … [...]
[...] http://blog.jdevelop.eu/?p=26Session; /** * Wrapper-class for OrdersDAO (and all other DAO’s). * If you want to use an other HibernateUtil, just change the * ConnectionProvider.class -Binding in GuiceModule or create * other Provider- and Connection classes. … [...]
[...] you dont want to use IoC and Google Guice, you can also set up the hibernate utility without Guice. With Guice: Without Guice: I modified the AbstractHibernateConnection class so that it actually uses [...]