2017-03-05 4 views
0

Webサービスの呼び出しごとに最大接続数を維持しています。 EntityManagerが毎回作成され、データベースへの新しい接続を作成しているように見えますが、接続を完全に閉じたり解放したりすることはありません。私は常に私の接続を最大限に使い、私は最初の呼び出しの後に再び接続したり質問を実行することはできません。Hibernate JPAが多すぎる接続

EntityManagerではなくSessionManager/SessionFactoryなどを使用する必要がありますか?

私も静的Connection cconnを使用せず、EntityManagerとの接続を維持してから、最後のブロックで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: [email protected]9 -- 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" 
+0

あなたは本当に各ビジネス/リポジトリユースケースで新しい 'EntityManagerFactory'を作成すべきではありません。それはあなたのアプリケーションが何の理由もありませんオーバーヘッドのかなりの量になります。通常、アプリケーションは起動時に 'EntityManagerFactory'または' SessionFactory'を生成し、ユースケースに必要に応じてそれぞれ 'EntityManager'インスタンスまたは' Session'インスタンスを作成するためにファクトリを再利用する必要があります。 – Naros

答えて

0

私ができるようにあなたのコンテナに依存することをお勧めしたいですそれはあなたの取引を管理します。 以下の回答では、JPA-Transactionを管理できるWebコンテナを使用していると想定しています。したがって

、あなたはRESOURCE_LOCALの上にpersistance.xml

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

なぜJTAを変更する必要がありますか?簡潔に :取引を自分で管理する必要はありません。 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はあなたのwebserviceにあなたのClub-jpa-serviceを注入し、それを使用する必要があるだけです。

+0

私はこれを撃つでしょう。私はローカルで私のアプリケーションがlocalhostとQA/PRに接続する必要があるので、接続の詳細を切り替えることができます。アマゾンに接続する必要があります。起動時に@PersistenceContext( "Hunting") 'を" Hunting "または" HuntingAmazon "に変更または設定できますか? – tiggles

+0

Persistence-unit-nameを変更したり、動的に変更することはお勧めしません。 (たとえあなたがMaven/Antスクリプトなどでもできるのですが) コンテナに依存している場合は、コンテナにdata-ressourceを定義し、JNDIで名前を付ける必要があります。 persistence.xmlでは、アクセス資格情報を定義する部分が、より良いサーバー構成に進むべきです。 '' ' jdbc/oracle '' ' を使用してデータ・リソースを呼び出すだけですか? どのサーバーを使用していますか?特定のコンテナの「JNDIデータソース」を検索します。 – The86Freak

関連する問題