web开发-SSH-hibernate4.3.8-HibernateSessionFactory.java

问题描述

SSH-hibernate4.3.8-HibernateSessionFactory.java

初学者问题:
1)web开发,哪里有靠谱的HibernateSessionFactory.java 及其对应的hibernate.cfg.xml?感觉自己手上的这两个文件的问题多多,各种debug,很耗时间
2) hibernate的jar包要放WEB-INF/lib目录下?又或者跟hibernate.cfg.xml里面的某个property的设置有关?

sever一开始起不来,网上搜了下,把hibernate的jar包要放WEB-INF/lib目录下,server就可以起来了。奇怪,struts的jar放WEB-INF/lib目录下可以理解,怎么hibernate的也要放在这个目录下?

开发环境
eclipse: Luna Service Release 1a (4.4.1)
mysql: 5.6
struts: 2.3.20

hibernate: 4.3.8

现象:
第一次从web访问,正常。说明struts, mysql工作都是正常的。
第二次起从web访问,报下面的错误。
将下面的代码注释掉后,再从web访问,每次正常了。问题是:一直不close SessionFactory 不会有问题吗? 是否要优化HibernateSessionFactory.java?

HibernateTestAction.java

 //sf.close();  即SessionFactory一直不close
 Debug - execute - after getSessionFactory
Debug - execute - throw exception
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:201)
    at org.hibernate.internal.AbstractSessionImpl.getJdbcConnectionAccess(AbstractSessionImpl.java:341)
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.<init>(JdbcCoordinatorImpl.java:114)
    at org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl.<init>(TransactionCoordinatorImpl.java:89)
    at org.hibernate.internal.SessionImpl.<init>(SessionImpl.java:258)

代码:
HibernateSessionFactory.java

 package hibernate;

import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

/**
 * Configures and provides access to Hibernate sessions, tied to the current
 * thread of execution. Follows the Thread Local Session pattern, see
 * {@link http://hibernate.org/42.html }.
 */

public class HibernateSessionFactory {
    private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        System.out.println("sessionFactory - on buildSessionFactory");
        try {
            Configuration cfg = new Configuration().configure();
            StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                                .applySettings(cfg.getProperties()).build();
            SessionFactory sessionFactory = cfg.buildSessionFactory(serviceRegistry);

            return sessionFactory;
        }
        catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.out.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        System.out.println("sessionFactory - on getSessionFactory");
        if (sessionFactory == null)
            System.out.println("build sessionFactory - fail");
        else
            System.out.println("build sessionFactory - succe");
        return sessionFactory;
    }

}

hibernate.cfg.xml

 <?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">
<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>
    <session-factory>
        <!--
        <property name="hibernate.transaction.factory_class">
        org.hibernate.transaction.JTATransactionFactory
        </property>
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
        -->        

        <property name="cache.use_query_cache">true</property>
        <property name="cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
        <property name="cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

        <property name="connection.username">root</property>
        <property name="connection.password">admin</property>

        <property name="connection.url">
            jdbc:mysql://localhost:3306/db_database10
        </property>
        <property name="dialect">
            org.hibernate.dialect.MySQLDialect
        </property>
        <property name="cache.use_query_cache">true</property>
        <property name="cache.provider_class">
            org.hibernate.cache.HashtableCacheProvider
        </property>
        <property name="show_sql">true</property>
        <property name="connection.driver_class">
            com.mysql.jdbc.Driver
        </property>
        <mapping resource="mapping.xml" />
    </session-factory>
</hibernate-configuration>

HibernateTestAction.java

 public class HibernateTestAction extends ActionSupport implements ModelDriven<Book> {
...
    public String execute() {
        SessionFactory sf =  HibernateSessionFactory.getSessionFactory();

        try {
            System.out.println("Debug - execute - after getSessionFactory ");

            Session s = sf.openSession();
            s.beginTransaction();
            System.out.println("Debug - execute - after beginTransaction ");

            String hql = "from Book";
            Query query;
            query = s.createQuery(hql);
            List<Book> books = query.list();
            dataMap.put("data", books);

            System.out.println("Debug - execute - query.list ");

            for(Book bookTemp: books)
            {
               System.out.println(bookTemp.toString());
            }
            s.getTransaction().commit();
            System.out.println("Debug - execute - after commit");
            s.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            System.out.println("Debug - execute - throw exception ");
            e.printStackTrace();
        }
        sf.close();

        dataMap.put("status", "SUCCESS");

        return SUCCESS;
    }
...
}

解决方案

我们一般采用spring来管理sessionFactory,如果用hibernate自己管理的话开发最好用单例模式创建sessionFactory,
sessionFactory只创建一次就可以,是不需要关闭的。因为session是线程不安全的,所以每次用hibenate的时候记得要
及时关闭session,即每次查询操作数据库的时候需要sessionFactory来openSession,每次操作完数据库或者查询完数据库
要记得及时close掉session就可以了。

如果你看过你的server的文件结构你就明白为什么所有jar包都放在WEB-INF/lib下,WEB-INF下放着你的所有的代码, 你的所有Java代码被编译成
classes文件放在了WEB-INF/classes中相当于src,所有jar包放在WEB-INF/jar下,WEB-INF中还有web.xml配置文件,WEB-INF外面放页面,相当于webroot

如果你觉得DEBUG多多,一个是删掉你的代码中的sysout,一个不显示你的sql语句,从hibernate.cfg.xml中
true中true改成false,一个是你是不是放hibernate包放进去日志包log4j系列,如果是就修改你的
log4j.properties文件,把里面的log4j.rootLogger=DEBUG改成log4j.rootLogger=info就可以大大减少你的DEBUG输出了。

解决方案二:

谢谢 kunkunqianqian。

用下面的HibernateSessionFactoryV1.java,问题解决了

package hibernate;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

/**
 * Configures and provides access to Hibernate sessions, tied to the
 * current thread of execution.  Follows the Thread Local Session
 * pattern, see {@link http://hibernate.org/42.html }.
 */
public class HibernateSessionFactoryV1 {
    /**
     * Location of hibernate.cfg.xml file.
     * Location should be on the classpath as Hibernate uses
     * #resourceAsStream style lookup for its configuration file.
     * The default classpath location of the hibernate config file is
     * in the default package. Use #setConfigFile() to update
     * the location of the configuration file for the current session.
     */
    private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
    private static org.hibernate.SessionFactory sessionFactory;
    private static Configuration configuration = new Configuration();
    private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
    private static String configFile = CONFIG_FILE_LOCATION;

    static {
        try {
            configuration.configure(configFile);
            StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                                                            .applySettings(configuration.getProperties()).build();
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        } catch (Exception e) {
            System.err.println("%%%% Error Creating SessionFactory %%%%");
            e.printStackTrace();
        }
    }

    private HibernateSessionFactoryV1() {
    }

    /**
    * Returns the ThreadLocal Session instance.  Lazy initialize
    * the <code>SessionFactory</code> if needed.
    *
    *  @return Session
    *  @throws HibernateException
    */
    public static Session getSession() throws HibernateException {
        System.out.println("Debug - on HibernateSessionFactoryV1.getSession ");
        Session session = (Session) threadLocal.get();

        if ((session == null) || !session.isOpen()) {
            if (sessionFactory == null) {
                rebuildSessionFactory();
            }

            session = (sessionFactory != null) ? sessionFactory.openSession()
                                               : null;
            threadLocal.set(session);
        }

        return session;
    }

    /**
    *  Rebuild hibernate session factory
    *
    */
    public static void rebuildSessionFactory() {
        try {
            configuration.configure(configFile);
            StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                                                            .applySettings(configuration.getProperties()).build();
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);

        } catch (Exception e) {
            System.err.println("%%%% Error Creating SessionFactory %%%%");
            e.printStackTrace();
        }
    }

    /**
    *  Close the single hibernate session instance.
    *
    *  @throws HibernateException
    */
    public static void closeSession() throws HibernateException {
        Session session = (Session) threadLocal.get();
        threadLocal.set(null);

        if (session != null) {
            session.close();
        }
    }

    /**
    *  return session factory
    *
    */
    public static org.hibernate.SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    /**
    *  return session factory
    *
    *        session factory will be rebuilded in the next call
    */
    public static void setConfigFile(String configFile) {
        HibernateSessionFactoryV1.configFile = configFile;
        sessionFactory = null;
    }

    /**
    *  return hibernate configuration
    *
    */
    public static Configuration getConfiguration() {
        return configuration;
    }
}

时间: 2024-08-30 13:06:15

web开发-SSH-hibernate4.3.8-HibernateSessionFactory.java的相关文章

java web开发 高并发处理

java 高并发 java处理高并发高负载类网站中数据库的设计方法(java教程,java处理大量数据,java高负载数据)  一:高并发高负载类网站关注点之数据库  没错,首先是数据库,这是大多数应用所面临的首个SPOF.尤其是Web2.0的应用,数据库的响应是首先要解决的. 一般来说MySQL是最常用的,可能最初是一个mysql主机,当数据增加到100万以上,那么,MySQL的效能急剧下降.常用的优化措施是M-S(主-从)方式进行同步复制,将查询和操作和分别在不同的服务器上进行操作.我推荐的

用Eclipse Europa进行Web开发,第1部分

成为一名 Web开发人员恰逢其时.从来不曾像现在一样有如此多的技术选择 .大量优秀的开源 Web 服务器.数据库.编程语言和开发框架供您使用.无论 您希望使用哪种技术组合,都存在可以提高生产力的集成开发环境 (IDE): Eclipse.本教程是三部分系列教程 "Web development with Eclipse Europa" 的第 1 部分,将介绍如何通过 Eclipse 实现使用 Java 技术.PHP 和 Ruby 的 Web 开发,查看如何使用 Eclipse 的最新版

插件-有关web开发上传图片的问题

问题描述 有关web开发上传图片的问题 大家好...没经验真的很可怕...希望有高人能解决我几个疑问.. 上传多张图片的时候,例如上传10张,看了很多上传插件,发现图片都是立刻 上传上去的....问题来了..例如我在发表帖子,除了图片之外,我还要填写帖子 的标题...如果是这样的话,后台数据库又是怎么对应上的呢...当然,方法我觉得 还是有的,笨方法就是把每张图片的反馈的id记下来,再一起随着标题文字再次发送.后台 数据库里循环更新....问题来了...如果客户端上传好图片之后,忽然不想发表了.

table-java web开发,ssh框架,我想询问下载jsp里,下面的表格怎么制作?求大神指导

问题描述 java web开发,ssh框架,我想询问下载jsp里,下面的表格怎么制作?求大神指导 下边是形成的效果,行是固定的就是1到4:列也是固定的就是第一年到第六年. 跪求大神指导 解决方案 http://blog.csdn.net/cuishijin/article/details/1577009 这里面总结了一些资料,你可以去看下 解决方案二: table tr td

新书出版:Java Web开发技术大全——JSP+Servlet+Struts 2+Hibernate+Sp

本文为原创,如需转载,请注明作者和出处,谢谢! 作者:李宁 图书详细信息: ISBN:9787302195757 定价:79.8元 印次:1-1 装帧:平装 印刷日期:2009-4-23   图书简介: SSH是目前最流行的Java Web开发技术.本书通过对SSH中的各种技术循序渐进地讲解,使读者尽快掌握开发基于SSH的Web程序的方法.本书内 容包括Web客户端技术.JSP/Servlet技术.Struts 2(拦截器.类型转换.输入校验.上传和下载文件.Struts 2的各种标签.对 AJ

新书出版:Java Web开发技术大全——JSP+Servlet+Struts 2+Hibernate+Spring+Ajax (附源代码)

本文为原创,如需转载,请注明作者和出处,谢谢! 源代码下载 作者:李宁 图书详细信息: ISBN:9787302195757 定价:79.8元 印次:1-1 装帧:平装 印刷日期:2009-4-23 图书简介: SSH是目前最流行的Java Web开发技术.本书通过对SSH中的各种技术循序渐进地讲解,使读者尽快掌握开发基于SSH的Web程序的方法.本书内 容包括Web客户端技术.JSP/Servlet技术.Struts 2(拦截器.类型转换.输入校验.上传和下载文件.Struts 2的各种标签.

Tomcat与Java Web开发技术详解连载之一

web|详解 本章介绍如何在Tomcat上创建和发布Web应用.这里首先讲解Tomcat的目录结构以及Web应用的目录结构,接着介绍如何将HTML.Servlet.JSP和Tag Library部署到Web应用中,然后介绍把整个Web应用打包并发布的方法,最后介绍如何在Tomcat上配置虚拟主机. 本章侧重于讨论Web应用的结构和发布方法,所以没有对本章的Servlet和JSP的例子进行详细解释,关于Servlet和JSP的技术可以分别参考其它章节的内容. 2.1 Tomcat的目录结构 在To

Tomcat与Java Web开发技术详解连载之二

web|详解 2.2.4 部署HTML文件 在helloapp目录下加入index.htm文件,这个文件仅仅用来显示一串带链接的字符"Welcome to HelloApp", 它链接到login.jsp文件.以下是index.htm文件的代码: <html><head><title>helloapp</title></head><body ><p><font size="7"

Tomcat与Java Web开发技术详解连载之三

web|详解 2.2.8 创建并发布WAR文件 Tomcat既可以运行采用开放式目录结构的Web应用,也可以运行WAR文件.在本书配套光盘的sourcecode/chapter2/helloapp目录下提供了所有源文件,只要把整个helloapp目录拷贝到/webapps目录下,即可运行开放式目录结构的helloapp应用.在Web应用的开发阶段,为了便于调试,通常采用开放式的目录结构来发布Web应用,这样可以方便地更新或替换文件.如果开发完毕,进入产品发布阶段,应该将整个Web应用打包为WAR