如何正确关闭与mysql服务器

时间:2015-04-26 14:31:36

标签: java mysql hibernate

我关注了official hibernate tutorial以及其他一些描述如何开始使用Hibernate的内容(例如Hibernate Many To Many Mapping Join Tables Annotation and XML Configuration Example)。

我在Windows 7下运行本地MySQL服务器,一切似乎都运行正常。我可以使用XML配置文件连接,Hibernate将数据插入我的测试数据库,但我无法正确关闭hibernate连接。我收到错误消息,即即使收到连接请求也没有正确关闭。

我google了一下,看到很多人不久前就有这个问题了,但是找不到最近有关如何解决这个问题的信息。

官方教程怎么可能导致这样的问题?感谢任何人如何解决如何解决这个问题。

编辑:这是我收到的警告信息。程序打印出Item2 ID = 53行和之后弹出的WARNING消息之间有大约15秒的暂停:

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

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

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的版本:

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

如果有人能指出我如何解决这个问题的方向,我会非常感激。

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

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的相关部分:

<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文件:

<?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服务器端的连接时,我可以看到em.close()实际上关闭了连接。不知何故,只有游泳池没有正确关闭。我的输出是

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)

谢谢你,周末愉快。斯蒂芬

1 个答案:

答案 0 :(得分:5)

感谢您的有益评论。我找到了解决方案。一个人需要使用附加标志-Dexec.cleanupDaemonThreads=false来调用maven。如果有人知道为什么会这样,请告诉我。但是,这绝对解决了上述问题。所以最后,它实际上并没有与hibernate有任何关系,而是maven的一个问题。如果您不希望每次要执行项目时都输入mvn compile exec:java -Dexec.mainClass=com.journaldev.hibernate.main.HibernateManyToManyMain -Dexec.cleanupDaemonThreads=false,也可以添加

<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结果。再说一次,如果有人可以解释这实际上做了什么或为什么这是必要的,我会很好奇,因为我花了将近一个星期来解决这个问题。感谢大家的帮助。