2017-03-05 3 views
0

Ich halte die maximale Anzahl von Verbindungen nach jedem Web-Service-Anruf. Es sieht so aus, als ob EntityManager jedes Mal erstellt wird und eine neue Verbindung zur Datenbank erstellt wird, die Verbindung jedoch nie vollständig geschlossen oder freigegeben wird. Ich bin immer meine Verbindungen aus, und ich kann nie wieder verbinden oder irgendwelche Abfragen nach den ersten Anrufen ausführen.Hibernate JPA zu viele Verbindungen

Muss ich SessionManager/SessionFactory oder etwas anstelle von EntityManager verwenden?

Ich versuchte auch nicht mit einer statischen Connection cconn und bekomme immer eine Verbindung mit EntityManager und dann schließen Sie die EM in einem endgültigen Block, aber ich bekomme immer noch den Fehler. Ich bin neu bei JPA, also ist es mein Design, meine Einstellungen, Code, alles?

eine Verbindung bekommen - 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> 

Getting die Club-Benutzer aus einer Funktion in meinem Webservice.

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

Verbindungsfehler

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" 

Edit: 1 Added c3po und die gleichen bekam "Zu viele Verbindungen" Fehler

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

Sie sollten wirklich nicht eine neue 'EntityManagerFactory' für jeden Geschäftsfall/Repository-Anwendungsfall erstellen. Das wird eine beträchtliche Menge an Overhead sein, die Ihre Anwendung ohne Grund haben wird. Normalerweise sollte Ihre Anwendung beim Start eine 'EntityManagerFactory' oder eine' SessionFactory' generieren und die Factory wiederverwenden, um entweder 'EntityManager'- oder 'Session'-Instanzen zu erstellen, wie es für Ihre Anwendungsfälle erforderlich ist. – Naros

Antwort

0

ich auf dem Behälter schlagen würde verlassen zu lassen Es verwaltet Ihre Transaktionen. In meiner folgenden Antwort gehe ich daher davon aus, dass Sie einen beliebigen WebContainer verwenden, der JPA-Transaktionen verwalten kann - was die meisten State-of-the-Art-fähig sind.

daher müssen Sie Ihre persistance.xml

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

Warum JTA über RESOURCE_LOCAL ändern? Kurz gesagt: Sie müssen die Transaktionen nicht selbst verwalten. https://stackoverflow.com/a/28998110/3507356

Dann stellen Sie 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; 
} 

ich zur Zeit dann assume-Club-Klasse als @Entity bezeichnet ist mit der richtigen Feld Anmerkung usw.

Ich denke, können Sie dann loswerden Ihr ConnectionUtil dann, da Sie nur Ihren Club-jpa-Service in Ihren Webservice einspeisen und nutzen müssen.

+0

Ich werde das eine Chance geben. Ich habe meine Persistenz, Verbindungsdetails zu wechseln, weil ich lokal meine Anwendung brauche, um mich mit localhost zu verbinden, und in QA/PR ich brauche es, um mich mit Amazon aws zu verbinden.Kann ich '@PersistenceContext (" Hunting ") beim Start von" Hunting "oder" HuntingAmazon "ändern oder einstellen? – tiggles

+0

Es ist nicht empfehlenswert, den Persistenz-Einheitennamen zu ändern oder dynamisch zu machen. (Auch wenn Sie mit maven/ant-scripts usw. arbeiten könnten) Wenn Sie sich auf Ihren Container verlassen, sollten Sie die Datenressource in Ihrem Container definieren und über JNDI benennen. Also in der persistence.xml sollte der Teil, wo Sie Ihre Zugangsdaten definieren, besser zur Server-Konfiguration gehen. Dann benennen/rufen Sie einfach Ihre Datenressource über: '' ' jdbc/oracle' '' Welchen Server benutzen Sie? Suche nach "JNDI Dataresource" für Ihren spezifischen Container. – The86Freak