我创建了一个这样的DAO:它基于:Hibernate: CRUD Generic DAO
public class Dao{
SessionFactory sessionFactory;
// initialise session factory
public User save(User o){
return (User) sessionFactory.getCurrentSession().save(o);
}
public User get(Long id){
return (User) sessionFactory.getCurrentSession().get(User.class, id);
}
public User void saveOrUpdate(User o){
sessionFactory.getCurrentSession().saveOrUpdate(o);
}
现在,如果我的sessionFactory在DAO或其他类中,这一切都很好。但我的问题是从servletContextListener调用SessionFactory:这是我在侦听器中的代码:
public void contextInitialized(ServletContextEvent event) {
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
try {
sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
event.getServletContext().setAttribute("factory", sessionFactory);
} catch(Exception e) {
e.printStackTrace();
StandardServiceRegistryBuilder.destroy( registry );
}
}
除了在DAO中实际包装servletRequest之外,在这种情况下如何从DAO调用SessionFactory?
答案 0 :(得分:1)
我强烈不鼓励将Hibernate SessionFactory
存储到Servlet的ServletContext
中。另外,请让您的DAO使用您的休眠Session
。
为了解决你的Hibernate SessionFactory
实例化一次的问题,我创建了一个单例类来管理它:
/**
*
*/
package za.co.sindi.persistence.util;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
/**
* This is a Hibernate utility class that strictly uses the Hibernate 4.x library.
*
* @author Buhake Sindi
* @since 26 November 2012
*
*/
public final class HibernateUtils {
private static final Logger logger = Logger.getLogger(HibernateUtils.class.getName());
private static Configuration configuration;
private static SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;
private static final ThreadLocal<Session> sessionThread = new ThreadLocal<Session>();
private static final ThreadLocal<Interceptor> interceptorThread = new ThreadLocal<Interceptor>();
static {
try {
configuration = new Configuration();
serviceRegistry = new StandardServiceRegistryBuilder().build();
sessionFactory = configuration.configure().buildSessionFactory(serviceRegistry);
} catch (HibernateException e) {
logger.log(Level.SEVERE, "Error intializing SessionFactory.", e.getLocalizedMessage());
throw new ExceptionInInitializerError(e);
}
}
/**
* Private constructor
*/
private HibernateUtils() {}
/**
* @return the sessionFactory
*/
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
/**
* Retrieves the current session local to the thread.
*
* @return Hibernate {@link Session} for current thread.
* @throws HibernateException when Hibernate has a problem opening a new session.
*/
public static Session getSession() {
Session session = sessionThread.get();
if (session == null) {
Interceptor interceptor = getInterceptor();
if (interceptor != null) {
session = getSessionFactory().withOptions().interceptor(interceptor).openSession();
} else {
session = getSessionFactory().openSession();
}
if (session != null) {
sessionThread.set(session);
}
}
return session;
}
/**
* Closes the Hibernate Session (created from the <code>getSession()</code> session.
*/
public static void closeSession() {
Session session = sessionThread.get();
sessionThread.set(null);
if (session != null && session.isOpen()) {
session.close();
}
}
/**
* Registers a Hibernate {@link Interceptor}.
* @param interceptor
*/
public static void registerInterceptor(Interceptor interceptor) {
interceptorThread.set(interceptor);
}
/**
* Get the registered Hibernate Interceptor.
* @return
*/
public static Interceptor getInterceptor() {
return interceptorThread.get();
}
}
在我的DAO中,我只是将会话检索为HibernateUtils.getSession();
。
这样,我的MVC应用程序没有引用我的特定DAO实现。
我希望这会有所帮助。