繁体   English   中英

Hibernate JPA连接过多

[英]Hibernate JPA too many connections

每次Web服务调用后,我一直保持连接数上限。 看起来好像每次都在创建EntityManager并创建到数据库的新连接,但它从未完全关闭或释放该连接。 我总是最大程度地利用我的连接,并且在首次通话后我再也无法连接或运行任何查询。

我是否需要使用SessionManager / SessionFactory或其他方法来代替EntityManager?

我也尝试过不使用静态Connection cconn并保持与EntityManager的连接,然后在finally块中关闭em,但是我仍然收到错误。 我是JPA的新手,所以它是我的设计,设置,代码,所有内容吗?

获取连接-ConnectionUtil.java

public static Connection cconn = null;

public static Connection conn(){

        try {
            if(ConnectionUtil.cconn != null && !ConnectionUtil.cconn.isClosed()){
                return cconn;
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Connection conn = null;
        try {
            String lcp = ConnectionUtil.getLcp();
            logging.info("LCP : " + lcp);

            EntityManagerFactory factory = null;
            Map<String,Object> prop = null;

            String url ,password, user, connString;

            // Set default Connection details
            if(lcp == null){
                factory = Persistence.createEntityManagerFactory(LOCAL_PER);
                prop = factory.getProperties();

                url = (String) prop.get("javax.persistence.jdbc.url");
                password = (String)  prop.get("javax.persistence.jdbc.password");
                user = (String)  prop.get("javax.persistence.jdbc.user");
                connString = url +"?user="+user+"&password="+password;

                connString = "jdbc:mysql://localhost:3306/"+ConnectionUtil.DATABASE+"?" + "user=root&password=password";
                logging.info("Setting EntityManager to: default values");
                logging.info("Using string: "+ connString);
                Properties properties = new Properties();
                properties.put("connectTimeout", "20000");
                conn = DriverManager.getConnection(connString,properties);
                cconn = conn;
            }

persistance.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" 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">

    <persistence-unit name="Hunting" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/database"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="password"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>


            <!-- Hibernate properties -->
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.format_sql" value="false" />
            <property name="hibernate.connection.release_mode" value="on_close" />
            <property name="hibernate.connection.pool_size" value="100" />


            <!-- Configuring Connection Pool -->
            <property name="hibernate.c3p0.min_size" value="5" />
            <property name="hibernate.c3p0.max_size" value="20" />
            <property name="hibernate.c3p0.timeout" value="20" />
            <property name="hibernate.c3p0.max_statements" value="50" />
            <property name="hibernate.c3p0.idle_test_period" value="2000" />
        </properties>
    </persistence-unit>

从我的Web服务中的功能获取俱乐部用户。

public static Club getClubById(long id){
        Club cc = new Club();
        EntityManager em = null;
        try{
            em =  ConnectionUtil.getEnitityManager();
            cc = em.find(Club.class, id );
            cc.buildClubUsers();
        }finally{
            if(em != null){
                em.close();
            }
        }
        return cc;
    }

连接错误

15:32:26.315 [http-bio-8080-exec-7] WARN org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator - HHH000022: c3p0 properties were encountered, but the org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider provider class was not found on the classpath; these properties are going to be ignored.
15:32:26.315 [http-bio-8080-exec-7] INFO org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl - HHH000402: Using Hibernate built-in connection pool (not for production use!)
15:32:26.315 [http-bio-8080-exec-7] INFO org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl - HHH000115: Hibernate connection pool size: 100
15:32:26.315 [http-bio-8080-exec-7] INFO org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl - HHH000006: Autocommit mode: true
15:32:26.315 [http-bio-8080-exec-7] INFO org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl - HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/database]
15:32:26.315 [http-bio-8080-exec-7] INFO org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl - HHH000046: Connection properties: {user=root, password=password, autocommit=true, release_mode=on_close}
15:32:26.315 [http-bio-8080-exec-7] DEBUG org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl - Opening new JDBC connection
15:32:26.316 [http-bio-8080-exec-7] WARN org.hibernate.engine.jdbc.internal.JdbcServicesImpl - HHH000342: Could not obtain connection to query metadata : Data source rejected establishment of connection,  message from server: "Too many connections"

编辑:1添加了c3po并得到相同的“太多连接”错误

Mar 05, 2017 3:46:17 PM com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask run
WARNING: com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@214b8c9 -- Acquisition Attempt Failed!!! Clearing pending acquires. While trying to acquire a needed new resource, we failed to succeed more than the maximum number of allowed acquisition attempts (30). Last acquisition attempt exception: 
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection,  message from server: "Too many connections"

我建议依靠您的容器来管理您的交易。 因此,在我的以下回答中,我假设您正在使用能够管理JPA-Transaction的任何WebContainer-大多数最新技术都可以。

因此,您必须更改您的persistance.xml

<persistence-unit name="Hunting" transaction-type="JTA">

为什么使用JTA而不是RESOURCE_LOCAL? 简而言之:您不必自己管理交易。 https://stackoverflow.com/a/28998110/3507356

然后调整你的POJO

@PersistenceContext("Hunting")
EntityManager em;

public static Club getClubById(long id){
    Club cc = new Club();
    EntityManager em = null;
    try{
        // em =  ConnectionUtil.getEnitityManager();
        // EM is injected
        cc = em.find(Club.class, id );
        cc.buildClubUsers();
    }finally{
        if(em != null){
            em.close();
        }
    }
    return cc;
}

然后,我目前假设您的俱乐部班级被注释为具有适当字段注释等的@Entity。

我猜您随后可以摆脱ConnectionUtil的麻烦,因为您只需要将Club-jpa-service注入到Web服务中并使用它即可。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM