Закрыть SessionFactory в спящем режиме 4.3
Я обновляю свой Hibernate до последней версии. С моим старым HibernateUtil.java
у меня не было проблем, но при его обновлении SessionFactory, похоже, больше не закрывается.
это мой новая HibernateUtil.java
класс:
import org.hibernate.HibernateException;
import org.hibernate.cfg.Configuration;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
Configuration configuration = new Configuration().configure();
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(builder.build());
} catch (HibernateException ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void closeSessionFactory() {
sessionFactory.close();
}
}
это мой старый HibernateUtil.java
класс:
import org.hibernate.cfg.Configuration;
import org.hibernate.SessionFactory;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory from standard (hibernate.cfg.xml)
// config file.
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Log the exception.
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void closeSessionFactory() {
sessionFactory.close();
}
}
это мой спящий режим.контекстно-свободная грамматика.в 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="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mydatabase</property>
<property name="hibernate.connection.username">user</property>
<property name="hibernate.connection.password">pass</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">false</property>
<property name="format_sql">false</property>
<property name="use_sql_comments">false</property>
<!-- Use the thread as the context -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- Use these files for mapping configuration -->
<mapping resource="test/Person.hbm.xml"/>
</session-factory>
</hibernate-configuration>
код в котором я создаю сессии:
public class Helper {
Session session = null;
public Helper() {
this.session = HibernateUtil.getSessionFactory().getCurrentSession();
}
public List getPeople(int id) {
...
}
}
Главная метод:
public static void main(String args[]) {
Logger log = Logger.getLogger("org.hibernate");
log.setLevel(Level.WARNING);
Helper helper = new Helper();
List<Person> people = helper.getPeople(1);
for (int i = 0; i < people.size(); i++) {
System.out.println("people " + i + ": " + people.get(i).getID());
}
HibernateUtil.closeSessionFactory();
}
3 ответов
вы правы, в Hibernate 4.3 появляется ошибка.x, в котором поток, порожденный пулом соединений по умолчанию Hibernate, не очищается при завершении работы. Я подал ошибку здесь (пожалуйста, голосуйте!):
https://hibernate.atlassian.net/browse/HHH-8896
пока у вас есть два варианта. Вы можете добавить метод в HibernateUtil и использовать его, чтобы заставить пул соединений очистить себя в конце вашего приложения исполнение:
public static void stopConnectionProvider() {
final SessionFactoryImplementor sessionFactoryImplementor = (SessionFactoryImplementor) sessionFactory;
ConnectionProvider connectionProvider = sessionFactoryImplementor.getConnectionProvider();
if (Stoppable.class.isInstance(connectionProvider)) {
((Stoppable) connectionProvider).stop();
}
}
это работает,но это уродливо, хаки, использует устаревший метод и т. д. Лучшим решением было бы просто использовать "реальный" пул соединений, например c3p0, который можно включить, просто добавив следующие свойства в спящий режим.контекстно-свободная грамматика.XML-код:
<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.idle_test_period">100</property>
<property name="hibernate.c3p0.max_size">10</property>
<property name="hibernate.c3p0.max_statements">10</property>
<property name="hibernate.c3p0.min_size">10</property>
<property name="hibernate.c3p0.timeout">100</property>
обратите внимание, что если вы используете другой пул соединений, вы должны удалить это свойство пула соединений, которое в настоящее время находится в вашей конфигурации:
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
Edit: для использования пула соединений c3p0 вы также нужна зависимость hibernate-c3p0. Пример Maven для 4.3.0-SNAPSHOT из репозитория моментальных снимков Hibernate:
<repositories>
...
<repository>
<id>hibernate-snapshots</id>
<url>http://snapshots.jboss.org/maven2/</url>
</repository>
...
</repositories>
<dependencies>
...
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>4.3.0-SNAPSHOT</version>
</dependency>
...
<dependencies>
проблема, похоже, уже решена в Hibernate версии 4.3.5 .
sessionFactory.close();
работает в моей программе.
отпустите serviceRegistry, когда основное приложение завершится.
public class Service {
private SessionFactory factory;
private ServiceRegistry serviceRegistry;
public void initialize() throws Exception{
Configuration configuration = new Configuration();
configuration.configure("com/jeecourse/config/hibernate.cfg.xml");
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(
configuration.getProperties()).build();
factory = configuration.buildSessionFactory(serviceRegistry);
}
public void close() throws Exception{
if(serviceRegistry!= null) {
StandardServiceRegistryBuilder.destroy(serviceRegistry);
}
}