Долгое время назад я создал один-класс-гибернации-Util, чтобы облегчить мою жизнь на действительно очень небольших приложений с использованием DetachedCriteria следующим образом:Насколько опасен компактный анти-шаблон, DetachedCriteria, DAO, используемый для спящего режима?
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.DetachedCriteria;
/* WARNING: This utility was projected only for applications of one operation per use per mapping!
Using it for multiple operations characterizes the anti-pattern "session-per-operation". */
public class HibernateUtil {
private static final int SEARCH = 0;
private static final int LIST = 1;
private static final int SAVE = 2;
private static final int UPDATE = 3;
private static final int SAVE_OR_UPDATE = 4;
private static final int DELETE = 5;
private static final int MERGE = 6;
private static SessionFactory SESSION_FACTORY;
// Single session factory instantiation
static {SESSION_FACTORY = new Configuration().configure().buildSessionFactory();}
// Opens the session and executes only one operation on the transaction
private static Object executeTransaction(Object object, int operation) {
Object output = null;
Session session = SESSION_FACTORY.openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
switch (operation) {
case SEARCH: output = ((DetachedCriteria) object).getExecutableCriteria(session).uniqueResult(); break;
case LIST: output = ((DetachedCriteria) object).getExecutableCriteria(session).list(); break;
case SAVE: session.save(object); break;
case UPDATE: session.update(object); break;
case SAVE_OR_UPDATE: session.saveOrUpdate(object); break;
case DELETE: session.delete(object); break;
case MERGE: session.merge(object); break;
default: throw new HibernateException("No operation was executed on the database.");
}
transaction.commit();
} finally {
session.close();
}
return output;
}
// Usable methods, named accordingly to the operation:
public static Object searchCriteria(DetachedCriteria criteria) {return executeTransaction(criteria, SEARCH);}
public static List<?> listCriteria(DetachedCriteria criteria) {return (List<?>) executeTransaction(criteria, LIST);}
public static void save(Object object) {executeTransaction(object, SAVE);}
public static void update(Object object) {executeTransaction(object, UPDATE);}
public static void saveOrUpdate(Object object) {executeTransaction(object, SAVE_OR_UPDATE);}
public static void delete(Object object) {executeTransaction(object, DELETE);}
public static void merge(Object object) {executeTransaction(object, MERGE);}
}
Это позволяет мне взаимодействовать с базой данных по телефону HibernateUtil.searchCriteria()/listCriteria()/save()/update()/saveOrUpdate()/delete()/merge()
, но я фактически использую его в очень редких ситуациях (крошечные приложения) из-за его сеанса за операцию.
Проблема в том, что я только что узнал, что мои коллеги сотрудничали с ним в больших приложениях, перебегая к использованию надлежащих шаблонов DAO. Моя вина. Меня беспокоят возможные побочные эффекты, такие как накладные расходы или перегрузка, но я не знаю точно, с какими проблемами я должен беспокоиться. Является ли это достаточно рискованным для меня, чтобы начать переделывать DAO в своих приложениях?
Может ли кто-нибудь из вас более опытный программист или ребята из DBA поделится мной каким-то светом, здесь? Я бы очень признателен.
EDIT
Изменено его закрыть сессию. То, что я делаю сейчас, чтобы избежать ленивых ошибок инициализации, заключается в установке lazy="false"
в каждом сопоставлении «один-два-один» в hbm.xml.