Skip to content

Instantly share code, notes, and snippets.

@dulichan
Created March 24, 2013 17:54
Show Gist options
  • Save dulichan/5232836 to your computer and use it in GitHub Desktop.
Save dulichan/5232836 to your computer and use it in GitHub Desktop.
Part of my Hibernate Helper library.
package org.dchan.orm;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.proxy.HibernateProxy;
/**
* Copyright (c) 2013 Dulitha Wijewantha (http://www.dulithawijewantha.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* This is the backbone of persistence in the Application.
* {@link HbHelperAbstract} provides the following features
*
* <ul>
* <li>Can get the SessionFactory for advance functions outside of the helper</li>
* <li>A commit method to persist the session to the database</li>
* <li>Method to begin a new transaction</li>
* <li>Creation of queries and allowing query cache</li>
* <li>Getter for the current transaction of the factory</li>
* <li>A global get method for all entities</li>
* <li>Creation of an example for Criteria queries</li>
* <li>Clear the cache of the whole application</li>
* <li>Global merge for detached object</li>
* <li>Global evict method</li>
* </ul>
*
* Important point to note here is that {@link HbHelperAbstract} before was
* created in a Static basis. But in now it's extended to two subclasses
*
* @author Chan (Dulitha R. Wijewantha [email protected])
*
* @version 2.0
*/
public abstract class HbHelperAbstract {
static SessionFactory factory;
/**
* Getter for the SessionFactory
*
* @return SessionFactory
*/
public SessionFactory getSessionFactory() {
return factory;
}
/**
* This method is to be called when the Session Factory needs to be
* refreshed
*/
public abstract void startFactory();
/**
* This method handles the exceptional cases
*/
public RuntimeException commit(boolean hook) {
try {
getTranscation().commit();
return null;
} catch (RuntimeException e) {
e.printStackTrace();
getTranscation().rollback();
if (hook) {
// This part is there if we want to setup log functionality or
// use it to display errors
}
throw e;
}
}
public RuntimeException commit() {
return commit(true);
}
/**
* This method creates a new Transactions to work with the database but take
* note that this method doesn't affect the database. Only when the
* transaction is committed the database is affected
*/
public void beginTranscation() {
getSessionFactory().getCurrentSession().beginTransaction();
}
/**
* This method creates a Query object from a string and begins a transaction
* to work with the database. This also set the querie's cache mode to true
*
* @param s
* - The HQL query string
*
* @return the Query object
*/
public Query createQuery(String s) {
beginTranscation();
Query query = getCurrentSession().createQuery(s);
query.setCacheable(true);
return query;
}
/**
* A global get method to get anytype of object from the database.
*
* @param c
* - The class of the object
* @param id
* - The identity value of the object
*
* @return - the requested Object
*/
public Object get(Class c, Integer id) {
beginTranscation();
return getCurrentSession().get(c, id);
}
/**
* Getter for the current Session
*
*
* @return Session
*/
public Session getCurrentSession() {
return getSessionFactory().getCurrentSession();
}
/**
* Getter for the current Transaction
*
*
* @return Transaction
*/
public Transaction getTranscation() {
return getCurrentSession().getTransaction();
}
/**
* This method creates an example from the object sent and gives an example
* object to be used for Criteria Queries
*
* @param instance
* - The Object that needs to be created the example from
*
* @return - The example object
*/
public Example createExample(Object instance) {
return Example.create(instance).ignoreCase()
.enableLike(MatchMode.START);
}
/**
* Used to evict a cache region if specified... Useful for applications for
* long run
*
* @param cacheRegion
*/
public void clearQuery(String cacheRegion) {
beginTranscation();
getSessionFactory().evictQueries(cacheRegion);
commit();
}
/**
* This method is used to clear the Cache of the Hibernate Session factory
*/
public void clearCache() {
beginTranscation();
getCurrentSession().clear();
getSessionFactory().evictQueries();
try {
Map<String, ClassMetadata> classesMetadata = getSessionFactory()
.getAllClassMetadata();
for (String entityName : classesMetadata.keySet()) {
getSessionFactory().evictEntity(entityName);
}
} catch (Exception e) {
}
commit();
}
/**
* Used to evict an object our of Hibernate
*
* @param obj
*/
public void evict(Object obj) {
getCurrentSession().evict(obj);
}
/**
* When there is multiple sessions involved in Hibernate an object of
* previous session needs to be merged with the object in the current
* session.
*
*
*
* @param obj
* Object
* @return Merged object
*/
public Object merge(Object obj) {
return getCurrentSession().merge(obj);
}
/**
* This method encapsulates the NamedQueries in Hibernate. We can send in
* the Parameter list with key, value list and this method would
* automatically map them to the named query
*
* @param string
* String
* @param parameterList
* Object[]
* @return Query instance
*/
public Query getNameQuery(String string, Object... parameterList) {
beginTranscation();
Query namedQuery = getCurrentSession().getNamedQuery(string);
for (int i = 0; i < parameterList.length; i++) {
Object key = parameterList[i];
Object value = parameterList[++i];
if (value instanceof String) {
namedQuery.setString(key.toString(), value.toString());
} else if (value instanceof Short) {
namedQuery.setShort(key.toString(), (Short) value);
} else if (value instanceof Byte) {
namedQuery.setByte(key.toString(), (Byte) value);
} else if (value instanceof Persistent_Model) {
namedQuery.setEntity(key.toString(), value);
} else if (value instanceof Date) {
namedQuery.setDate(key.toString(), (Date) value);
} else if (value instanceof Integer) {
namedQuery.setInteger(key.toString(), (Integer) value);
}
}
return namedQuery;
}
/**
* Transaction unmanaged Save bulk method to save a set of objects
*
* @param set
*/
public void saveBulk(Set set) {
for (Iterator iterator = set.iterator(); iterator.hasNext();) {
Persistent_Model object = (Persistent_Model) iterator.next();
object.attachDirty();
}
}
public <T> T initializeAndUnproxy(T entity) {
if (entity == null) {
throw new NullPointerException(
"Entity passed for initialization is null");
}
Hibernate.initialize(entity);
if (entity instanceof HibernateProxy) {
entity = (T) ((HibernateProxy) entity)
.getHibernateLazyInitializer().getImplementation();
}
return entity;
}
public void executeProcedure(String procedureName, Object... parameters) {
StringBuffer query = new StringBuffer("CALL " + procedureName + "(");
for (int i = 0; i < parameters.length; i++) {
String string = parameters[i].toString();
++i;
query.append(":" + string + ",");
}
query.deleteCharAt(query.length() - 1);
query.append(")");
SQLQuery createSQLQuery = getCurrentSession().createSQLQuery(
query.toString());
for (int i = 0; i < parameters.length; i++) {
Object object = parameters[i];
if (object instanceof String) {
createSQLQuery.setString(object.toString(),
parameters[++i].toString());
} else if (object instanceof Integer) {
createSQLQuery.setInteger(object.toString(),
Integer.valueOf(parameters[++i].toString()));
}
}
createSQLQuery.executeUpdate();
}
/**
* Re-read the state of the given instance from the underlying database
*
* @param obj
*/
public void refresh(Object obj) {
getCurrentSession().refresh(obj);
}
}
package org.dchan.orm;
/**
*
* Copyright (c) 2013 Dulitha Wijewantha (http://www.dulithawijewantha.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Can be used to create ones own {@link HbHelperObj} for customized needs.
*
* @author Chan (Dulitha R. Wijewantha [email protected])
* @version 2.0
*/
public class HbHelperObj extends HbHelperAbstract {
@Override
public void startFactory() {
}
}
package org.dchan.orm;
import org.hibernate.cfg.AnnotationConfiguration;
/**
* Copyright (c) 2013 Dulitha Wijewantha (http://www.dulithawijewantha.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
*
* To be used under conditions where one single factory is involved. Where
* switching of the factory to a different datasource is not required.
*
* @author Chan (Dulitha R. Wijewantha [email protected])
* @version 2.0
*/
public class HbHelperSingle extends HbHelperAbstract {
private static HbHelperSingle pool;
private static String url;
private static String password;
private static String schema;
private static String user;
private static boolean isProduction = false;
boolean isInit = false;
/**
* Init variable setup to create the Singleton {@link HbHelperSingle}
*
* @param url
* @param user
* @param password
* @param schema
*/
public static void init(String url, String user, String password,
String schema) {
HbHelperSingle.url = url;
HbHelperSingle.password = password;
HbHelperSingle.user = user;
HbHelperSingle.schema = schema;
}
/**
* A method to set production level
*
* @param flag
*/
public static void setProduction(boolean flag) {
HbHelperSingle.isProduction = flag;
}
public static HbHelperSingle getInstance() {
if (pool == null) {
pool = new HbHelperSingle();
}
return pool;
}
// private constructor for singleton
private HbHelperSingle() {
}
@Override
public void startFactory() {
AnnotationConfiguration configuration = new AnnotationConfiguration()
.configure();
configuration.setProperty("hibernate.connection.url", url);
configuration.setProperty("hibernate.connection.username", user);
configuration.setProperty("hibernate.connection.password", password);
configuration.setProperty("hibernate.default_schema", schema);
if (isProduction) {
configuration.setProperty("hibernate.show_sql", "true");
}
factory = configuration.buildSessionFactory();
}
}
package org.dchan.orm;
import java.io.Serializable;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.LockMode;
import org.hibernate.SessionFactory;
/**
*
* Copyright (c) 2013 Dulitha Wijewantha (http://www.dulithawijewantha.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* A base class to be extended by all the Hibernate Model objects. The class
* provides basic facilities of CRUD operations. Logging is also enabled. This
* class should be customized so that HibernateHelper can be injected. Currently
* the class is using the {@link HbHelperSingle} as the helper.
*
* @author Chan (Dulitha R. Wijewantha [email protected])
* @version 2.0
*/
public abstract class Persistent_Model {
private final Log log;
/**
* Gets the Logger in the Constructor
*/
public Persistent_Model() {
log = LogFactory.getLog(this.getClass());
}
private final SessionFactory sessionFactory = getSessionFactory();
/**
* This method depends on the HibernateHelper to obtain the SessionFactory
* Model
*
* @return Session Factory
*/
protected SessionFactory getSessionFactory() {
try {
return HbHelperSingle.getInstance().getSessionFactory();
} catch (Exception e) {
log.error("Could not locate SessionFactory", e);
throw new IllegalStateException("Could not locate SessionFactory");
}
}
public void persist() {
log.debug("persisting " + this.getClass() + " instance");
try {
sessionFactory.getCurrentSession().persist(this);
log.debug("persist successful");
} catch (RuntimeException re) {
log.error("persist failed", re);
throw re;
}
}
public void attachDirty() {
log.debug("attaching dirty " + this.getClass() + " instance");
try {
sessionFactory.getCurrentSession().saveOrUpdate(this);
log.debug("attach successful");
} catch (RuntimeException re) {
log.error("attach failed", re);
throw re;
}
}
public void attachClean() {
log.debug("attaching clean " + this.getClass() + " instance");
try {
sessionFactory.getCurrentSession().lock(this, LockMode.NONE);
log.debug("attach successful");
} catch (RuntimeException re) {
log.error("attach failed", re);
throw re;
}
}
public void delete() {
log.debug("deleting " + this.getClass() + " instance");
try {
sessionFactory.getCurrentSession().delete(this);
log.debug("delete successful");
} catch (RuntimeException re) {
log.error("delete failed", re);
throw re;
}
}
/**
* Merge method
*
* @return Persistent_Model
*/
public Persistent_Model merge() {
log.debug("merging " + this.getClass() + " instance");
try {
Persistent_Model result = (Persistent_Model) sessionFactory
.getCurrentSession().merge(this);
log.debug("merge successful");
return result;
} catch (RuntimeException re) {
log.error("merge failed", re);
throw re;
}
}
/**
* The method is used to get a object via the HibernateHelper
*
* @param id
* - {@link java.io.Serializable}
* @return Persistent_Model
*/
public Persistent_Model findById(Serializable id) {
log.debug("getting " + this.getClass() + " instance with id: " + id);
try {
Persistent_Model instance = (Persistent_Model) sessionFactory
.getCurrentSession().get(
"app.model." + this.getClass() + "", id);
if (instance == null) {
log.debug("get successful, no instance found");
} else {
log.debug("get successful, instance found");
}
return instance;
} catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
}
/**
* Find an object via an example. The method internally use criteria queries
*
* @param instance
* Persistent_Model
* @return List<Persistent_Model>
*/
public List<Persistent_Model> findByExample(Persistent_Model instance) {
log.debug("finding " + instance.getClass().getName()
+ " instance by example");
try {
List<Persistent_Model> results = sessionFactory.getCurrentSession()
.createCriteria(instance.getClass().getName())
.add(HbHelperSingle.getInstance().createExample(instance))
.list();
log.debug("find by example successful, result size: "
+ results.size());
return results;
} catch (RuntimeException re) {
log.error("find by example failed", re);
throw re;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment