【发布时间】:2015-04-29 15:11:49
【问题描述】:
我已经为我的 Spring 应用程序配置了 Hibernate。我有一个名为 hibernateUtil.java 的文件,它为 Hibernate 创建了一个新会话。问题是我什么时候应该调用它的getSession 方法?有没有更好的方法来解决这个问题?
Hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/mydb
</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">12</property>
<!-- SQL dialect -->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="current_session_context_class">thread</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping class="com.myproject.model.business" />
</session-factory>
</hibernate-configuration>
HibernateUtil.java
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class HibernateUtil {
private static ServiceRegistry serviceRegistry;
private static final ThreadLocal<Session> threadLocal = new ThreadLocal();
private static SessionFactory sessionFactory;
private static SessionFactory configureSessionFactory() {
try {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
} catch (HibernateException e) {
e.printStackTrace();
}
return sessionFactory;
}
static {
try {
sessionFactory = configureSessionFactory();
} catch (Exception e) {
e.printStackTrace();
}
}
private HibernateUtil() {
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static Session getSession() throws HibernateException {
Session session = threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession()
: null;
threadLocal.set(session);
}
return session;
}
public static void rebuildSessionFactory() {
try {
sessionFactory = configureSessionFactory();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
if (session.isOpen()) {
session.close();
}
}
}
}
我也发现了这个tutorial,但我不确定它是否可靠。建议使用 Spring bean 配置文件进行 Hibernate 配置。
【问题讨论】:
-
在控制器方法中使用
HibernateUtil.getSession()的目的是什么?您的控制器代码中没有任何内容需要数据库交互,那么您为什么要获得会话呢?推荐的模式是基于每个 HTTP 请求创建会话。这在Hibernate documentation 中有解释。 -
@manish 我更新了问题,我只是把它放在控制器中以显示问题没有具体原因。
-
@manish 表示我不知道应该在何时何地调用 getsession 方法。
-
看看 Spring ORM 模块中的OpenSessionInViewFilter。由于您已经在使用 Spring,您可以考虑将 Spring ORM 模块添加到您的应用程序中,摆脱您的自定义
HibernateUtils类并让 Spring 管理您的 Hibernate 会话。 -
您正在使用 Spring,然后让 Spring 为您完成困难的工作。放弃
HibernateUtil类,让 spring 担心打开和关闭会话,这将为您省去麻烦并真正简化您的代码。我强烈建议阅读Spring reference guide。
标签: java spring hibernate spring-mvc configuration