如何正确关闭与MySQL服务器的休眠会话 [英] How to properly close hibernate session with mysql server

查看:82
本文介绍了如何正确关闭与MySQL服务器的休眠会话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遵循了官方的休眠教程,还有其他一些描述如何开始使用Hibernate的方法(例如休眠多对多映射联接表注释和XML配置示例).

I followed the official hibernate tutorial and also several others that describe how to get started with Hibernate (e.g. Hibernate Many To Many Mapping Join Tables Annotation and XML Configuration Example).

我有一个在Windows 7下运行的本地MySQL Server,一切似乎都正常运行.我可以使用XML配置文件进行连接,并且Hibernate将数据插入测试数据库中,但是我无法正确关闭hibernate连接.我收到以下错误消息:即使连接已正确关闭,该连接也未正确关闭.

I have a local MySQL Server running under Windows 7 and everything seems to work fine. I can connect using the XML configuration file and Hibernate inserts data into my test database but I cannot properly close the hibernate connection. I get the error message that the connection was not properly closed even if it received the request to do so.

我四处搜寻,发现很多人在不久前遇到了这个问题,但是找不到有关如何解决该问题的最新信息.

I googled around and saw that many people had that problem a while ago, but could not find any recent information on how to solve the problem.

官方教程怎么可能导致这样的问题?感谢您提供任何有关如何解决此问题的建议.

How is it possible that the official tutorial leads to such a problem? Thank you for anyone of how to suggest of how to tackle this problem.

这是我收到的警告消息.在程序打印出Item2 ID = 53行和随后弹出警告消息之间,大约需要15秒钟的暂停时间:

This is the warning messages that I get. There is about a 15s pause between the program printing out the Item2 ID=53 line and the WARNING messages popping up afterwards:

Hibernate: insert into ITEM (item_desc, item_price) values (?, ?)
Hibernate: insert into ITEM (item_desc, item_price) values (?, ?)
Hibernate: insert into CART (cart_total) values (?)
Before committing transaction
Hibernate: insert into CART_ITEMS (cart_id, item_id) values (?, ?)
Hibernate: insert into CART_ITEMS (cart_id, item_id) values (?, ?)
Hibernate: insert into CART_ITEMS (cart_id, item_id) values (?, ?)
Cart ID=53
Cart1 ID=54
Item1 ID=54
Item2 ID=53
[WARNING] thread Thread[Abandoned connection cleanup thread,5,com.journaldev.hibernate.main.HibernateManyToManyMain] was interrupted but is still aliv
e after waiting at least 15000msecs
[WARNING] thread Thread[Abandoned connection cleanup thread,5,com.journaldev.hibernate.main.HibernateManyToManyMain] will linger despite being asked t
o die via interruption
[WARNING] NOTE: 1 thread(s) did not finish despite being asked to  via interruption. This is not a problem with exec:java, it is a problem with the ru
nning code. Although not serious, it should be remedied.
[WARNING] Couldn't destroy threadgroup org.codehaus.mojo.exec.ExecJavaMojo$IsolatedThreadGroup[name=com.journaldev.hibernate.main.HibernateManyToManyM
ain,maxpri=10]
java.lang.IllegalThreadStateException
        at java.lang.ThreadGroup.destroy(ThreadGroup.java:775)
        at org.codehaus.mojo.exec.ExecJavaMojo.execute(ExecJavaMojo.java:328)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:862)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:286)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:197)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 27.936 s
[INFO] Finished at: 2015-04-28T13:11:56+02:00
[INFO] Final Memory: 12M/33M
[INFO] ------------------------------------------------------------------------

这是我的hibernate.cfg.xml

Here is my hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost/test</property>
        <property name="hibernate.connection.username">test</property>
        <property name="hibernate.connection.password">test</property>        
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

        <property name="hibernate.current_session_context_class">thread</property>
        <property name="hibernate.show_sql">true</property>

        <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>

        <mapping resource="com/journaldev/hibernate/model/cart.hbm.xml" />
        <mapping resource="com/journaldev/hibernate/model/item.hbm.xml" />
    </session-factory>
</hibernate-configuration>

这是我从上面的手册中复制的HibernateUtil:

This is the HibernateUtil that I copied from the manual above:

package com.journaldev.hibernate.util;

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 sessionFactory;

    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            Configuration configuration = new Configuration();
            configuration.configure("hibernate.cfg.xml");
            System.out.println("Hibernate Configuration loaded");

            ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                    .applySettings(configuration.getProperties()).build();
            System.out.println("Hibernate serviceRegistry created");

            SessionFactory sessionFactory = configuration
                    .buildSessionFactory(serviceRegistry);

            return sessionFactory;
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            ex.printStackTrace();
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        if (sessionFactory == null)
            sessionFactory = buildSessionFactory();
        return sessionFactory;
    }

}

这是要执行的相关类

package com.journaldev.hibernate.main;

import java.util.HashSet;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import com.journaldev.hibernate.model.Cart;
import com.journaldev.hibernate.model.Item;
import com.journaldev.hibernate.util.HibernateUtil;

public class HibernateManyToManyMain {

    //Saving many-to-many where Cart is primary
    public static void main(String[] args) {

        Item iphone = new Item();
        iphone.setPrice(100); iphone.setDescription("iPhone");

        Item ipod = new Item();
        ipod.setPrice(50); ipod.setDescription("iPod");

        Set<Item> items = new HashSet<Item>();
        items.add(iphone); items.add(ipod);

        Cart cart = new Cart();
        cart.setItems(items);
        cart.setTotal(150);

        Cart cart1 = new Cart();
        Set<Item> items1 = new HashSet<Item>();
        items1.add(iphone);
        cart1.setItems(items1);
        cart1.setTotal(100);

        SessionFactory sessionFactory = null;
        try{
        sessionFactory = HibernateUtil.getSessionFactory();
        Session session = sessionFactory.getCurrentSession();
        Transaction tx = session.beginTransaction();
        session.save(cart);
        session.save(cart1);
        System.out.println("Before committing transaction");
        tx.commit();
        sessionFactory.close();

        System.out.println("Cart ID="+cart.getId());
        System.out.println("Cart1 ID="+cart1.getId());
        System.out.println("Item1 ID="+iphone.getId());
        System.out.println("Item2 ID="+ipod.getId());

        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(sessionFactory != null && !sessionFactory.isClosed()) sessionFactory.close();
        }

    }

}

我希望命令sessionFactory.close()能够正确关闭并关闭所有内容.这是我与maven命令mvn compile exec:java -Dexec.mainClass=com.journaldev.hibernate.main.HibernateManyToManyMain一起使用的版本:

I would have expected that the command sessionFactory.close() would properly shutdown and close everything. Here are the versions that I am using with the maven command mvn compile exec:java -Dexec.mainClass=com.journaldev.hibernate.main.HibernateManyToManyMain:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.journaldev.hibernate</groupId>
    <artifactId>HibernateManyToManyMapping</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.9.Final</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-c3p0</artifactId>
            <version>4.3.9.Final</version>
        </dependency>   
    </dependencies>

</project>

如果有人能指出我解决该问题的方向,我将非常感激.

If anybody could point me to a direction of how to solve this problem, I would be very thankful.

JPADemo.java的新试用版.我仍然遇到同样的问题:

New trial with JPADemo.java. I am still having the same problem:

package com.cjg;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import com.cjg.Employee;


public class JPADemo
{
        public static void main(String[] args)
    {
                EntityManagerFactory emf = Persistence.createEntityManagerFactory("cjg-JPA");
                EntityManager em = emf.createEntityManager();

                em.getTransaction().begin();
                //Employee employee = new Employee();
                //employee.setName("Chandan");
                //System.out.println("COMITTING");
                //em.persist(employee);
                em.getTransaction().commit();
                System.out.println("COMITTING finished");

                em.close();
                emf.close();
                //System.out.println("after EntityManager.close()");

                //System.exit(0);
    }
}

pom.xml的相关部分:

relevant part of pom.xml:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>4.3.9.Final</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.35</version>
</dependency>

我的persistence.xml文件:

my persistence.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
        version="2.0">

        <persistence-unit name="cjg-JPA">
            <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
            <property name="hibernate.hbm2ddl.auto" value="create" />
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
            <property name="hibernate.connection.username" value="test" />
            <property name="hibernate.connection.password" value="test" />
            <property name="hibernate.connection.url" value="jdbc:mysql://localhost/test" />
        </properties>
        </persistence-unit>
</persistence>

我可能正在使用旧版本的内容吗?我通常对编程有相当的经验,并且知道如何对代码进行故障排除,但是我似乎根本不了解导致此问题的原因.在MySQL Server端查看连接时,我可以看到em.close()实际上关闭了连接.不知何故,只有池未正确关闭.我的输出是

Am I maybe using an old version of something? I am fairly experienced with programming in general and know how to troubleshoot code but I don't seem to understand the cause of this problem at all. When looking at the connections at the MySQL Server side, I can see that em.close() actually closes the connection. Somehow only the pool is not closed properly. My output is

INFO: HHH000230: Schema export complete
COMITTING finished
Mai 01, 2015 1:08:51 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH000030: Cleaning up connection pool [jdbc:mysql://localhost/test]
[WARNING] thread Thread[Abandoned connection cleanup thread,5,com.cjg.JPADemo] was interrupted but is still alive after waiting at least 15000msecs
[WARNING] thread Thread[Abandoned connection cleanup thread,5,com.cjg.JPADemo] will linger despite being asked to die via interruption
[WARNING] NOTE: 1 thread(s) did not finish despite being asked to  via interruption. This is not a problem with exec:java, it is a problem with the ru
nning code. Although not serious, it should be remedied.
[WARNING] Couldn't destroy threadgroup org.codehaus.mojo.exec.ExecJavaMojo$IsolatedThreadGroup[name=com.cjg.JPADemo,maxpri=10]
java.lang.IllegalThreadStateException
        at java.lang.ThreadGroup.destroy(ThreadGroup.java:775)
        at org.codehaus.mojo.exec.ExecJavaMojo.execute(ExecJavaMojo.java:328)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:862)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:286)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:197)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)

谢谢,祝您周末愉快.斯蒂芬

Thank you and have a nice weekend. Stephan

推荐答案

感谢您的有用评论.我找到了解决方案.需要使用附加标志-Dexec.cleanupDaemonThreads=false来调用maven.如果有人知道为什么会这样,请告诉我.但是,这肯定解决了上述问题.因此,最后,它实际上与休眠无关,而与Maven有关.如果不想每次执行项目都输入mvn compile exec:java -Dexec.mainClass=com.journaldev.hibernate.main.HibernateManyToManyMain -Dexec.cleanupDaemonThreads=false,也可以添加

thank you for your helpful comments. I have found the solution. One needs to call maven with the additional flag -Dexec.cleanupDaemonThreads=false. If anybody knows why this is the case, please let me know. However, this definitely solves the above problem. So in the end, it did not actually have anything to do with hibernate but was a problem with maven instead. If you don't want to enter mvn compile exec:java -Dexec.mainClass=com.journaldev.hibernate.main.HibernateManyToManyMain -Dexec.cleanupDaemonThreads=false everytime you want to execute the project, you can also add

<project>
...
<build>
<plugins>
<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <version>1.4.0</version>
  <executions>
    <execution>
      <goals>
        <goal>java</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
       <mainClass>com.cjg.JPADemo</mainClass>
       <cleanupDaemonThreads>false</cleanupDaemonThreads>
  </configuration>
</plugin>
</plugins>
</build>

</project>

到您的pom.xml以实现saim结果.再说一次,如果有人可以解释这实际上是做什么的或为什么这样做是必要的,我会很好奇,因为花了我近一个星期的时间才解决了这个问题.谢谢大家的帮助.

to your pom.xml to achieve the saim result. Again, if anybody can explain what this actually does or why this is necessary, I would be very curious, because it took me nearly a week to solve this issue. Thank you to everybody for your help.

这篇关于如何正确关闭与MySQL服务器的休眠会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆