假设你有一个应用程序,登录系统时会初始化很多信息,比如使用ajax同时初始化两类信息,这时如果你的hibernate还没初始化信息,就会有两个线程同时进行初始化操作。这时hibernate就会发现两个相同的hbm配置文件被读取,所以,问题发生了。
这怪谁?其实是我们自己的问题,如果你出现了上面的问题,就需要看看你的获取session的机制是否正常了
这是使用myeclipse自动生成的session工厂类:
package com.dcsoft.sbgl.hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Session;
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 HibernateSessionFactory {
/**
* 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 String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static final ThreadLocal threadLocal = new ThreadLocal();
private static Configuration configuration = new Configuration();
private static org.hibernate.SessionFactory sessionFactory;
private static String configFile = CONFIG_FILE_LOCATION;
private HibernateSessionFactory() {
}
/**
* Returns the ThreadLocal Session instance. Lazy initialize
* the <code>SessionFactory</code> if needed.
*
* @return Session
* @throws HibernateException
*/
public static Session getSession() throws HibernateException {
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);
sessionFactory = configuration.buildSessionFactory();
} 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) {
HibernateSessionFactory.configFile = configFile;
sessionFactory = null;
}
/**
* return hibernate configuration
*
*/
public static Configuration getConfiguration() {
return configuration;
}
}
请看一下标红的部分:
if (sessionFactory == null)
这时就会进行初始化操作,如果两个线程同时到了这里,嘿嘿…………
解决方法:
1 初始化:在启动应用的时候配置一个servlet进行初始化hibernate操作,无论做什么都行,只要使用hibernate进行数据库操作。
如果你觉得这种方法还不保险,那就使用第二招:加锁!
2 将红色部分加上:
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
synchronized (lockObj) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
}
session = (sessionFactory != null) ? sessionFactory.openSession()
: null;
threadLocal.set(session);
}
return session;
}
但总感觉这种方法会影响效率,感觉能用第一种方法最好
分享到:
相关推荐
这样,在Hibernate启动时,就会使用我们的自定义类来初始化数据库连接。 ##### 3. 利用反射修改配置 通过反射机制,我们可以获取到`Environment`类中的属性,进而修改`Properties`对象中的配置信息。具体实现方式...
- 初始化SessionFactory:读取配置文件,创建SessionFactory对象。 - 创建Session:SessionFactory创建Session,它是与数据库交互的单线程对象。 - 开启事务:在进行数据库操作前,通常会开启一个事务。 - CRUD...
在实际应用中,开发者会根据需求创建自己的实体类,并编写相应的.hbm.xml映射文件,然后在hibernate.cfg.xml中配置数据库连接信息,最后引入hibernate3.jar,就可以通过Hibernate提供的API来执行CRUD(创建、读取、...
此外,对于需要初始化数据的测试,可以在配置文件中定义`<hibernate-generator>`元素,配合`@TestExecutionListeners`注解,使用`HibernateTestExecutionListener`来自动加载测试数据。或者,可以手动在测试方法中...
4. 初始化SessionFactory:在代码中通过Configuration类加载配置文件,然后创建SessionFactory对象。 5. 使用Session:通过SessionFactory获取Session对象,进行数据操作。 对于Maven工程,配置过程有所不同: 1....
在整合这三个框架时,Spring3作为核心,负责管理其他组件的生命周期,包括初始化Hibernate SessionFactory和Struts2的Action实例。Hibernate4则作为数据访问层,通过Spring的JdbcTemplate或HibernateTemplate来透明...
对于网站启动初始化,Spring框架提供了`ContextLoaderListener`,它会在Web应用启动时加载配置文件并创建ApplicationContext。在这个过程中,可以定义一些初始化Bean,例如数据源、SessionFactory等,这些都会在Web...
在这个场景中,异常信息表明在调用`Configuration.doConfigure()`方法时发生了错误,其原因是DOM4J在读取XML配置文件时遇到了问题。具体错误为“Content is not allowed in prolog”,这意味着在XML文档的声明之前...
SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。这里用到了工厂模式。需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory...
描述中的"系统初始化监听器"指的是在JEECG启动时执行的一些初始化任务,可能包括加载配置、建立数据库连接、初始化数据、设置缓存等。这种监听器通常实现了Spring的`ApplicationListener`接口,监听特定的`...
1. **SessionFactory初始化**:通过Configuration类读取配置文件并构建SessionFactory。 2. **Session操作**:SessionFactory创建Session对象,Session是数据库会话,用于执行CRUD操作。 3. **事务处理**:使用...
这是初始化Hibernate的核心,用于加载配置信息并生成SessionFactory。 3. SessionFactory 是所有Session的工厂,它负责管理所有数据库的连接。 4. Session 代表一次数据库会话,提供了与数据库交互的方法,如...
Configuration负责读取配置文件并初始化SessionFactory,SessionFactory是线程安全的,用于创建Session实例。Session是与数据库进行交互的主要接口,而Transaction则管理数据库事务。Query接口允许我们执行复杂的...
4. 初始化SessionFactory:在应用程序启动时,根据配置文件创建SessionFactory实例,它是线程安全的,整个应用程序只需要一个。 5. 使用Session:通过SessionFactory获取Session实例,进行数据库操作。 案例中的源...
7. **操作流程**:在学习这个例子时,开发者通常会经历以下步骤:加载配置、初始化SessionFactory、打开Session、创建或获取实体对象、执行CRUD操作(创建、读取、更新、删除)、最后关闭Session。 通过分析这个...
2. **Hibernate配置**: 包含在JAR文件中的配置文件(如`hibernate.cfg.xml`)用于定义数据库连接参数、实体类映射信息等,是初始化Hibernate的重要步骤。 3. **Java 8特性支持**: Hibernate 5.0引入了对Java 8的...
2. SessionFactory接口:这是Hibernate的核心组件,它是线程安全的,用于初始化Hibernate并创建Session实例。SessionFactory对应于一个数据库连接源,一般情况下,应用程序只需要一个SessionFactory实例。如果存在多...
配置 Hibernate 包括设置实体映射文件、配置文件(hibernate.cfg.xml)以及初始化 SessionFactory。我们将一步步详细解释这些过程,并且记录下每一步的关键点,以便于日后回顾和学习。 1. **配置Hibernate3** - **...
这包括编写Hibernate配置文件(hibernate.cfg.xml),定义实体类(POJOs),以及创建映射文件(.hbm.xml)。映射文件描述了Java类与数据库表之间的对应关系。 **四、SessionFactory与Session** Hibernate的核心组件...