这是我的代码:
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">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/sakila</property>
<property name="connection.username">root</property>
<property name="connection.password"/>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.show_sql">false</property>
<mapping class="biz.tugay.saqila.model.Actor" />
</session-factory>
</hibernate-configuration>
HibernateUtil.java
package biz.tugay.saqila.dao;
/* User: koray@tugay.biz Date: 06/08/15 Time: 18:29 */
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 SessionFactory SESSION_FACTORY;
public static void buildSessionFactory() {
if (SESSION_FACTORY != null) {
return;
}
Configuration configuration = new Configuration();
configuration.configure();
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
SESSION_FACTORY = configuration.buildSessionFactory(serviceRegistry);
}
public static Session getCurrentSession() {
return SESSION_FACTORY.getCurrentSession();
}
public static void killSessionFactory() {
if (SESSION_FACTORY != null) {
SESSION_FACTORY.close();
}
}
}
和示例DAO类:
package biz.tugay.saqila.dao;
/* User: koray@tugay.biz Date: 06/08/15 Time: 18:37 */
import biz.tugay.saqila.model.Actor;
import org.hibernate.Session;
import java.util.List;
@SuppressWarnings("unchecked")
public class ActorDao {
public List<Actor> getAllActors() {
Session session = HibernateUtil.getCurrentSession();
session.beginTransaction();
List<Actor> actors = session.createQuery("FROM Actor").list();
session.close();
return actors;
}
public Actor getWithId(int id) {
Session session = HibernateUtil.getCurrentSession();
session.beginTransaction();
Actor actor = (Actor) session.get(Actor.class, id);
session.close();
return actor;
}
}
你可以看到我没有在任何地方调用 openSession ,只是 getCurrentSession 。但这是如何工作的?
此外,这是正确的做事方式还是我很幸运,这是有效的?
顺便说一下,我也有这个听众:
package biz.tugay.saqila.servlet;
/* User: koray@tugay.biz Date: 06/08/15 Time: 19:00 */
import biz.tugay.saqila.dao.HibernateUtil;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class HibernateConfigurator implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
HibernateUtil.buildSessionFactory();
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("Killing Session Factory.");
HibernateUtil.killSessionFactory();
}
}
答案 0 :(得分:2)
如果您将hibernate.current_session_context_class
设置为线程,则可以使用SessionFactory.getCurrentSession()
在应用程序的任何位置访问该会话。
如果您不希望将会话绑定到上下文,请使用OpenSession。在某些情况下,您可能需要一个不同的会话 - 除了一个绑定到上下文的会话,您可以使用OpenSession而不是currentSession。
SessionFactory.openSession()
总是会打开一个新的会话,一旦完成数据库操作,您必须关闭该会话。 SessionFactory.getCurrentSession()
返回绑定到上下文的会话,您无需关闭它。
每个应用程序永远不应该使用一个会话 - 会话不是线程安全对象,多个线程无法共享。始终使用一个会话交易强>
答案 1 :(得分:1)
获得当前会话。究竟“当前”的定义意味着由配置使用的CurrentSessionContext impl控制。
您正在使用ThreadLocalSessionContext。 Its javadoc说:
CurrentSessionContext impl,它通过当前执行线程来限定当前会话的概念。 [...]为了可用性,决定让这个默认impl在第一次请求时实际生成一个会话,然后在提交/回滚与该会话相关联的事务之后将其清理。
您不应该关闭以这种方式获得的会话。相反,您应该提交已经开始的事务。正如文档所述,这将关闭会话。