Java/Hibernate - 异常: 内部连接池已达到其最大大小,当前没有可用连接

14

我第一次在大学项目中使用Hibernate,我有点新手。我认为我按照我的教授和一些教程给出的所有指示进行了操作,但是我仍然不断收到标题中所述的异常:

Exception in thread "main" org.hibernate.HibernateException: The internal connection pool has reached its maximum size and no connection is currently available!

我想要做的是将一个对象 (AbitazioneDB) 存储到一个我已经创建的 MySql 数据库中。这是我的配置文件:

<?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>
        <!-- Connection to the database -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/AllarmiDomesticiDB</property>

        <!-- Credentials -->
        <property name="hibernate.connection.username">root</property>
        <property name="connection.password">password</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

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

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

        <property name="show_sql">true</property>

        <!-- Entity -->

        <mapping class="it.allarmiDomestici.centraleOperativaRemota.dbWrapper.AbitazioneDB" />

    </session-factory>
</hibernate-configuration>

这是我的AbitazioneDB类(我将省略getter和setter):

@Entity
@Table(name="abitazioni")
public class AbitazioneDB {

    @Id
    @GeneratedValue
    @Column(name="id")
    private Integer id;

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

    @Column(name="nome_proprietario")
    private String nomeProprietario;

    @Column(name="tel_proprietario")
    private String telProprietario;

    public AbitazioneDB(){
        super();
    }

    public AbitazioneDB save(){

        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session session = sf.getCurrentSession();
        session.beginTransaction();

        Integer id = (Integer) session.save(this);
        this.setId(id);

        session.getTransaction().commit();      
        session.close();

        return this;
    }
}

这是我的HibernateUtil类:

public class HibernateUtil {

    private static SessionFactory sessionFactory;

    private static SessionFactory createSessionFactory() {
        sessionFactory = new Configuration().configure().buildSessionFactory();
        return sessionFactory;
    }

    public static SessionFactory getSessionFactory() {
        if (sessionFactory == null)
            sessionFactory = createSessionFactory();

        return sessionFactory;
    }
}

这是我的TestHibernate类,其中包含main方法:

public class TestHibernate {

    public static void main(String[] args) {
        AbitazioneDB ab = new AbitazioneDB();

        ab.setIndirizzo("Via Napoli, 29");
        ab.setNomeProprietario("Mario Rossi");
        ab.setTelProprietario("3333333333");

        ab.save();

        System.out.println("Ok!");

    }
}

每当我运行TestHibernate时,总是会出现该异常,但我不知道为什么。也许我应该更改connection.pool_size属性,但如果我这样做,似乎只会得到更多的错误。有人可以帮帮我吗?


如果您通过getCurrentSession()获取了会话,请不要使用session.close()。这可能会耗尽您的连接池。 - 11thdimension
谢谢回答,但它没有奏效。仍然得到相同的异常。 - Alessandro
这意味着您的连接池已经用尽了所有的连接,是否存在太多长时间运行的数据库调用? - 11thdimension
这是我所做的第一个,也是唯一的(至少目前是)数据库调用。 - Alessandro
4个回答

23

你的连接池已经耗尽了连接,因为你在池中只使用了单个连接。

<property name="connection.pool_size">1</property>

将此属性更改为您感到舒适的值,例如 100


1
谢谢你的回答,但是正如我在原始帖子中所说,它似乎并没有帮助到我。 - Alessandro
另外,根据Hibernate的官方文档:“Hibernate自己的连接池算法相当基础。它旨在帮助您入门,并不适用于生产系统,甚至不适用于性能测试。为了获得最佳性能和稳定性,您应该使用第三方池。只需将hibernate.connection.pool_size属性替换为连接池特定设置即可关闭Hibernate的内部池。例如,您可能想使用c3p0。” - G. Ciardini

10

尝试这个:

HibernateUtil:

public static Session getHibernateSession() {

    final SessionFactory sf = new Configuration()
        .configure("yourConfig.cfg.xml").buildSessionFactory();

    // factory = new Configuration().configure().buildSessionFactory();
    final Session session = sf.openSession();
    return session;
    }

不要使用SessionFactory,改用Session:

final Session session = HibernateUtil.getHibernateSession();

然后使用:

 Transaction tx = session.beginTransaction();
 // all your methods
 tx.commit();
 session.close();
希望这可以帮到您。 如果您不需要连接池属性,实际上可以在hbm中不设置它。

谢谢您的回答,但仍然没有结果。 - Alessandro
@Alessandro,你尝试从你的配置XML中删除那个属性了吗? - Pritam Banerjee
@Alessandro 而不是将保存方法放在POJO类内部,您能否尝试将其放在主方法中? - Pritam Banerjee
是的,现在它给了我一些异常,以以下内容开头:ERROR: could not read a hi value com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'allarmidomesticidb.hibernate_sequence' doesn't exist然后是:Exception in thread "main" org.hibernate.exception.SQLGrammarException: error performing isolated work我需要手动先创建一些表吗? - Alessandro
我的最后一条评论是在从XML文件中删除属性之后的回复。现在我将尝试移动“保存”方法。 - Alessandro
显示剩余4条评论

4
<property name="connection.pool_size">1</property>

尝试将连接池大小更改为更大的值,比如100个或更多。

<property name="connection.pool_size">100</property>

8
这似乎是对此现有答案的重复。 - Pang

0

我也很高兴地通过将connection.pool_size属性的值增加到100来解决了这个问题。

<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">100</property>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接