【问题标题】:Java/Hibernate Error: Connection leak detected. The internal connection pool has reached its maximum size and no connection is currently availableJava/Hibernate 错误:检测到连接泄漏。内部连接池已达到其最大大小,当前没有可用连接
【发布时间】:2019-01-27 03:48:52
【问题描述】:

我是 Java/Hibernate 的新手,我不知道这个错误是什么意思。

ERROR: Connection leak detected: there are 1 unclosed connections upon shutting down pool jdbc:mysql://localhost:3306/hb_student_records?useSSL=false&serverTimezone=UTC
Exception in thread "main" org.hibernate.HibernateException: The internal connection pool has reached its maximum size and no connection is currently available!

我在 Stack Overflow 的其他论坛上查找了答案,但那里对我来说毫无意义。

我的班级如下:

创建学生演示

package com.rsharma.hibernate.demo;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.rsharma.hibernate.demo.entity.Student;

public class CreateStudentDemo {

    public static void main(String[] args) {

        // create session factory
        SessionFactory factory = new Configuration()
                                .configure("hibernate.cfg.xml")
                                .addAnnotatedClass(Student.class)
                                .buildSessionFactory();

        // create session
        Session session = factory.getCurrentSession();

        try {           
            // create a student object
            System.out.println("Creating new student object...");
            Student tempStudent = new Student("Rishav", "Sharma", "paul@luv2code.com");

            // start a transaction
            session.beginTransaction();

            // save the student object
            System.out.println("Saving the student...");
            session.save(tempStudent);

            // commit transaction
            session.getTransaction().commit();

            System.out.println("Done!");
        }
        finally {
            factory.close();
        }
    }

}

Student.java

package com.rsharma.hibernate.demo.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity 
@Table(name="student")
public class Student {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="id")
    private int id; 

    @Column(name="first_name")
    private String firstName; 

    @Column(name="last_name")
    private String lastName; 

    @Column(name="email")
    private String email; 



    public Student(){ 

    }


    public Student(String firstName, String lastName, String email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }


    public int getId() {
        return id;
    }


    public void setId(int id) {
        this.id = id;
    }


    public String getFirstName() {
        return firstName;
    }


    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }


    public String getLastName() {
        return lastName;
    }


    public void setLastName(String lastName) {
        this.lastName = lastName;
    }


    public String getEmail() {
        return email;
    }


    public void setEmail(String email) {
        this.email = email;
    }


    @Override
    public String toString() {
        return "Student [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + "]";
    }

}

还有我的 config.xml 文件

hibernate.cfg.xml

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

        <!-- JDBC Database connection settings -->
        <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/hb_student_records?useSSL=false&amp;serverTimezone=UTC</property>
        <property name="connection.username">hbstudent</property>
        <property name="connection.password">hbstudent</property>

        <!-- JDBC connection pool settings ... using built-in test pool -->
        <property name="connection.pool_size">1</property>

        <!-- Select our SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- Echo the SQL to stdout -->
        <property name="show_sql">true</property>

        <!-- Set the current session context -->
        <property name="current_session_context_class">thread</property>

    </session-factory>

</hibernate-configuration>

我不知道是什么导致我的连接打开,因为我在课堂上关闭了我的工厂并且会话是临时的。

【问题讨论】:

    标签: java hibernate


    【解决方案1】:

    我认为您还应该在关闭工厂对象之前刷新并关闭会话对象。

    【讨论】:

      【解决方案2】:

      在你的实体类中使用下面 @GeneratedValue(strategy = GenerationType.IDENTITY)

      【讨论】:

      • 欢迎来到 Stack Overflow!虽然此代码可能会回答问题,但提供有关 如何 和/或 为什么 解决问题的附加上下文将提高​​答案的长期价值。
      【解决方案3】:

      在 Student 类中,在第 14 行,您已将 Id 生成策略声明为:

      @GeneratedValue(strategy=GenerationType.AUTO)
      

      改成

      @GeneratedValue(strategy = GenerationType.IDENTITY)
      

      这将消除错误。

      查看 Hibernate Docs 以了解您的数据库支持哪一个。 以下是所有 4 种 ID 生成策略:

      • GenerationType.AUTO:为特定数据库选择合适的策略。
      • GenerationType.IDENTITY:使用数据库标识列分配主键。
      • GenerationType.SEQUENCE:使用数据库序列分配主键。
      • GenerationType.TABLE:使用底层数据库表分配主键以确保唯一性。

      【讨论】:

        【解决方案4】:

        此问题的快速解决方法是用旧的 Hibernate 5.2 jar 文件替换最新的 Hibernate 包。

        其实问题不在于连接池,try和catch块内有一些对象类型不匹配,你可以删除try和catch块,看看真正的异常是什么。

        也许 Hibernate 专家可以回答这个问题。

        当然,“在关闭工厂对象之前刷新和关闭会话对象”对您没有帮助。

        【讨论】:

          【解决方案5】:

          看我有你的疑问,请删除@GenerationType(Strategy=GeneratedValue.Identity)这一行, 因为我猜您在主键列中使用了自动增量。 @GenerationType(Strategy=GeneratedValue.Identity) 只应在您想在数据库中保存多个对象时使用。

          【讨论】:

            【解决方案6】:

            你应该改变

            @GeneratedValue(strategy = GenerationType.AUTO)
            

            @GeneratedValue(strategy = GenerationType.IDENTITY)
            

            然后它会起作用。

            【讨论】:

              【解决方案7】:

              为我解决的问题是为每个事务创建一个新的 EntityManager 并在每个事务之后像这样关闭它。

              } finally {
                  session.close();
                  entityManager.close();
              }
              

              【讨论】:

                【解决方案8】:

                聚会有点晚了,但问题仍然存在(Hibernate 5.6.3 final)。

                就我而言,上述解决方案均无效。

                当然,OP 问题中缺少的部分是session.close():但是,我已经准备好了,并且程序不断给出有关连接泄漏的错误消息。

                经过一番谷歌搜索,我发现过去默认的 Hibernate 池受到产生此问题的 bug 影响:Hibernate 的 Jira 中的相关票证(多个重复)已关闭并解决,但问题仍然存在。

                我通过使用c3p0 池而不是默认池来解决:将其添加到依赖项中就足够了:

                        <dependency>
                            <groupId>org.hibernate</groupId>
                            <artifactId>hibernate-c3p0</artifactId>
                            <version>5.6.3.Final</version>
                        </dependency>
                

                【讨论】:

                  猜你喜欢
                  • 2016-12-22
                  • 2020-03-09
                  • 2019-03-23
                  • 2016-12-23
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多