package com.simpletwitter.common;
import java.lang.reflect.Method;
import java.util.List;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Junction;
import org.hibernate.criterion.Restrictions;
public class DatabaseManager {
private static Configuration cfg;
private static SessionFactory sessionFactory;
private DatabaseManager() {
try {
cfg = new AnnotationConfiguration().configure("hibernate.cfg.xml");
String dialect = "org.hibernate.dialect.MySQLDialect";
cfg.setProperty("hibernate.dialect", dialect);
sessionFactory = cfg.buildSessionFactory();
} catch (Throwable ex) {
ex.printStackTrace();
throw new ExceptionInInitializerError(ex);
}
}
private Session getSession() {
return sessionFactory.openSession();
}
private static class LazyLoader {
public static DatabaseManager INSTANCE = new DatabaseManager();
}
public static DatabaseManager getInstance() {
return LazyLoader.INSTANCE;
}
private void begin(Session session) {
session.beginTransaction();
}
private void close(Session session) {
session.flush();
session.close();
}
private void commit(Session session) {
session.getTransaction().commit();
session.flush();
}
private void rollback(Session session) {
session.getTransaction().rollback();
session.flush();
}
@SuppressWarnings("unchecked")
public <T> T createObject(T obj) {
Session session = null;
T returnObj = null;
try {
session = getSession();
begin(session);
Long id = (Long) session.save(obj);
returnObj = (T) session.get(obj.getClass(), id);
commit(session);
} catch (Exception e) {
e.printStackTrace();
rollback(session);
} finally {
close(session);
}
return returnObj;
}
@SuppressWarnings("unchecked")
public <T> T getObjectByExample(T exampleObj) {
Session session = null;
T entity = null;
Criterion exampleCriterion = Example.create(exampleObj);
try {
session = getSession();
begin(session);
Criteria criteria = session.createCriteria(exampleObj.getClass())
.add(exampleCriterion);
entity = (T) criteria.uniqueResult();
commit(session);
} catch (Exception e) {
rollback(session);
} finally {
close(session);
}
return entity;
}
public <T> List<T> getAllObjects(Class<T> clazz) {
return getAllObjects(clazz, null);
}
@SuppressWarnings("unchecked")
public <T> List<T> getAllObjects(Class<T> clazz,
SimpleTwitterCriteria customCriteria) {
Session session = null;
List<T> entityList = null;
try {
session = getSession();
begin(session);
Criteria criteria = session.createCriteria(clazz);
addCustomCritetria(customCriteria, criteria);
entityList = criteria.list();
commit(session);
} catch (Exception e) {
e.printStackTrace();
rollback(session);
} finally {
close(session);
}
return entityList;
}
private void addCustomCritetria(SimpleTwitterCriteria customCriteria,
Criteria criteria) {
if (customCriteria != null) {
for (SimpleTwitterCriterion customCriterion : customCriteria
.getCriterionList()) {
addCriterion(customCriterion, criteria);
}
}
}
private void addCriterion(SimpleTwitterCriterion customCriterion,
Criteria criteria) {
SimpleTwitterCriterion.TYPE type = customCriterion.getType();
switch (type) {
case LOGICAL:
addLogical(customCriterion, criteria);
break;
case EXPRESSION:
addExpression(customCriterion, criteria);
break;
}
}
private void addCriterion(SimpleTwitterCriterion customCriterion,
Junction junction) {
SimpleTwitterCriterion.TYPE type = customCriterion.getType();
switch (type) {
case LOGICAL:
addLogical(customCriterion, junction);
break;
case EXPRESSION:
addExpression(customCriterion, junction);
break;
}
}
private void addExpression(SimpleTwitterCriterion customCriterion,
Junction junction) {
Criterion criterion = addExpression(customCriterion);
if (criterion != null)
junction.add(criterion);
}
private void addLogical(SimpleTwitterCriterion customCriterion,
Junction junction) {
Junction subJunction = addLogical(customCriterion);
if (subJunction != null)
junction.add(subJunction);
}
private void addLogical(SimpleTwitterCriterion customCriterion,
Criteria criteria) {
Junction junction = addLogical(customCriterion);
if (junction != null)
criteria.add(junction);
}
private Junction addLogical(SimpleTwitterCriterion customCriterion) {
SimpleTwitterCriterion.OPERATION oper = customCriterion.getOperation();
Junction junction = null;
switch (oper) {
case AND:
junction = Restrictions.conjunction();
break;
case OR:
junction = Restrictions.disjunction();
break;
}
if (customCriterion.hasCriterionList()) {
for (SimpleTwitterCriterion subCustCriterion : customCriterion
.getCriterionList()) {
addCriterion(subCustCriterion, junction);
}
}
return junction;
}
private void addExpression(SimpleTwitterCriterion customCriterion,
Criteria criteria) {
Criterion criterion = addExpression(customCriterion);
if (criterion != null)
criteria.add(criterion);
}
private Criterion addExpression(SimpleTwitterCriterion customCriterion) {
SimpleTwitterCriterion.OPERATION oper = customCriterion.getOperation();
Criterion criterion = null;
switch (oper) {
case EQ:
criterion = Restrictions.eq(customCriterion.getField(),
customCriterion.getValue());
break;
case NE:
criterion = Restrictions.ne(customCriterion.getField(),
customCriterion.getValue());
break;
case OR:
}
return criterion;
}
@SuppressWarnings("unchecked")
public <T> T getObject(Class<T> classObj, Long obj_id) {
Session session = null;
T domainObject = null;
try {
session = getSession();
begin(session);
domainObject = (T) session.get(classObj, obj_id);
commit(session);
} catch (Exception e) {
e.printStackTrace();
rollback(session);
} finally {
close(session);
}
return domainObject;
}
public <T> void updateObject(T obj) {
Session session = null;
try {
session = getSession();
begin(session);
session.update(obj);
commit(session);
} catch (Exception e) {
e.printStackTrace();
rollback(session);
} finally {
close(session);
}
}
@SuppressWarnings("unchecked")
public <T, V> List<T> getChildrenForParent(Long parentObjId,
Class<V> parentClass, Class<T> childClass) {
Session session = null;
List<T> childObjects = null;
try {
String joinColName = getJoinColumnName(childClass, parentClass);
session = getSession();
begin(session);
Criteria criteria = session.createCriteria(childClass).add(
Restrictions.eq(joinColName, parentObjId));
childObjects = criteria.list();
commit(session);
} catch (Exception e) {
e.printStackTrace();
rollback(session);
} finally {
close(session);
}
return childObjects;
}
public static final String DOT = ".";
public static final String PROPERTY_OBJ_ID = "objId";
private String getJoinColumnName(Class contCls, Class instCls) {
String columnName = "";
Method method;
try {
String clsName = instCls.getSimpleName();
String propertyName = clsName.substring(0, 1).toLowerCase()
+ clsName.substring(1);
method = contCls.getMethod("get" + clsName);
if (method.isAnnotationPresent(ManyToOne.class)
&& method.isAnnotationPresent(JoinColumn.class)) {
columnName = propertyName + DOT + PROPERTY_OBJ_ID;
}
} catch (SecurityException e) {
// Suppress the exception
} catch (NoSuchMethodException e) {
// Suppress the exception
}
return columnName;
}
public <T> void deleteObject(T obj) {
Session session = null;
try {
session = getSession();
begin(session);
session.delete(obj);
commit(session);
} catch (Exception e) {
e.printStackTrace();
rollback(session);
} finally {
close(session);
}
}
}