Près d'une SessionFactory dans Hibernate 4.3
Je me suis mise à niveau de mon Hibernation pour la dernière version. Avec mon vieux HibernateUtil.java
je n'avais pas de problèmes, mais lorsque la mise à niveau, de la SessionFactory ne semble pas près plus.
C'est mon nouveau HibernateUtil.java
classe:
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();
}
}
C'est mon vieux HibernateUtil.java
classe:
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();
}
}
C'est mon 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="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>
Code dans lequel j'ai créer la session:
public class Helper {
Session session = null;
public Helper() {
this.session = HibernateUtil.getSessionFactory().getCurrentSession();
}
public List getPeople(int id) {
...
}
}
Méthode principale:
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();
}
- Quand je lance mon
main
méthode, le programme ne s'arrête jamais, il ne cesse de courir, car il y a encore des session(s) de l'ouvrir. J'appelle lecloseSessionFactory()
comme je l'ai toujours fait, mais maintenant il ne fait pas les conséquence de stopper le programme, après l'exécution. - Poste le code dans lequel vous êtes la création de la session.
- Tout d'abord fermer à l'aide de votre session.close().
- Encore ne s'arrête pas, même si je ferme la session
Vous devez vous connecter pour publier un commentaire.
Vous avez raison, il semble y avoir un bug dans Hibernate 4.3.x dans lequel un thread généré par Hibernate par défaut du pool de connexion ne sont pas nettoyés lors de l'arrêt. J'ai déposé un bug ici (votez!):
https://hibernate.atlassian.net/browse/HHH-8896
Jusqu'à ce qu'il fixe, vous avez deux choix. Vous pouvez ajouter une méthode à votre HibernateUtil et l'utiliser pour forcer la connexion de la piscine à nettoyer lui-même jusqu'à la fin de votre application d'exécution:
Cela fonctionne, mais c'est moche, hacky, utilise une méthode dépréciée, etc. La meilleure solution serait d'utiliser un "vrai" pool de connexion, comme c3p0, qui peut être activé simplement en ajoutant les propriétés suivantes à votre hibernate.cfg.xml:
Notez que si vous utilisez un autre pool de connexion, vous devez supprimer cette connexion de la piscine de la propriété, qui est actuellement dans votre config:
Edit: pour utiliser c3p0 le regroupement de connexion, vous aurez également besoin de la mise en veille prolongée-c3p0 de dépendance. Maven exemple pour 4.3.0-instantanée de l'Hibernation des instantanés repo:
Le problème semble être déjà résolu dans Hibernate version 4.3.5 .
travaille dans mon programme.
La libération de la serviceRegistry quand l'application se termine.