0

Я работаю в приложении с Google Cloud SQL. Я использую Hibernate 4.2.0.Final, и я заметил, что после 8 часов бездействия мое соединение закрыто. Я искал в Интернете, и я не мог найти ничего эффективного для решения этой проблемы. Вся информация, которую я нашел, суммируется в этих статьях:Как решить тайм-аут Google CloudSQL за 8 часов?

  • Используйте пул соединений, где я должен указать более высокий тайм-аут. Я пытался использовать библиотеки c3p0 и DBCP 2.1.1, но ни одна из них не решила проблему.
  • Откройте соединение перед некоторым запросом и затем закройте его. Проблема в том, что я хотел бы использовать EntityManager для использования запросов с сущностями.

Вот что я сделал с DBCP 2.1.1 (http://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2/2.1.1). Проблема в том, что журналы Goggle App Engine показывают ExceptionInInitializerError, когда я пытаюсь использовать findAll в своем PersistenceService. Журналы также показывают, что мой DataSource (см. Ниже) нельзя отнести к String. Я не понимаю, почему.

Это PersistenceService я использую сейчас

package co.peewah.ems.utils; 

import com.google.appengine.api.utils.SystemProperty; 

import java.beans.PropertyVetoException; 
import java.io.IOException; 
import java.sql.SQLException; 
import java.util.AbstractMap.SimpleEntry; 
import java.util.Date; 
import java.util.GregorianCalendar; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.Properties; 
import java.util.UUID; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.persistence.EntityManager; 
import javax.persistence.EntityManagerFactory; 
import javax.persistence.Persistence; 
import javax.persistence.Query; 
import javax.persistence.TypedQuery; 
import javax.persistence.criteria.CriteriaQuery; 
import javax.persistence.criteria.Root; 

import org.hibernate.cfg.AvailableSettings; 


/** 
* 
* @author Muacito 
*/ 
public class PersistenceService 
{ 
    private static final EntityManagerFactory EMF = createEntityManagerFactory(); 

    private static EntityManager entityManager = EMF.createEntityManager(); 

    private static EntityManagerFactory createEntityManagerFactory() 
    { 
     //String mode = ""; 
     /* 
     if (SystemProperty.environment.value() == SystemProperty.Environment.Value.Development) 
     { 
      mode = "dev."; 
     } 
     */ 

     Map<String, Object> properties = new HashMap<>(); 

     //Properties properties = new Properties(); 

     //properties.put("javax.persistence.jdbc.driver", System.getProperty("persistence." + mode + "db.driver")); 
     //properties.put("javax.persistence.jdbc.url", System.getProperty("persistence." + mode + "db.url")); 
     //properties.put("javax.persistence.jdbc.user", System.getProperty("persistence." + mode + "db.user")); 
     //properties.put("javax.persistence.jdbc.password", System.getProperty("persistence." + mode + "db.password")); 
     try 
     { 
      properties.put(AvailableSettings.DATASOURCE, DataSource.getInstance()); 
     } catch (IOException | SQLException | PropertyVetoException e) 
     { 
      e.printStackTrace(); 
     } 


     System.out.println("----------------------------"); 
     System.out.println("----------------------------"); 
     System.out.println(properties); 
     System.out.println("----------------------------"); 
     System.out.println("----------------------------"); 

     return Persistence.createEntityManagerFactory("Demo", properties); 
    } 

    private static EntityManager getEntityManager() 
    { 
     if (!PersistenceService.entityManager.isOpen()) 
     { 
      PersistenceService.entityManager = PersistenceService.EMF.createEntityManager(); 
     } 

     return PersistenceService.entityManager; 
    } 

    public static <T> void create(T entity) 
    { 
     try 
     { 
      if (entity.getClass().getMethod("getId").invoke(entity) == null) 
      { 
       entity.getClass().getMethod("setId", String.class).invoke(entity, 
         UUID.randomUUID().toString().replace("-", "")); 
      } 

      if (entity.getClass().getMethod("getCreated").invoke(entity) == null) 
      { 
       entity.getClass().getMethod("setCreated", Date.class).invoke(entity, 
         GregorianCalendar.getInstance().getTime()); 
      } 

      getEntityManager().getTransaction().begin(); 

      getEntityManager().persist(entity); 

      getEntityManager().flush(); 

      getEntityManager().getTransaction().commit(); 

     } catch (Exception ex) 
     { 
      Logger.getLogger(PersistenceService.class.getName()).log(Level.SEVERE, null, ex); 
      getEntityManager().getTransaction().rollback(); 
     } 
    } 

    public static <T> void edit(T entity) 
    { 
     try 
     { 
      if (entity.getClass().getMethod("getUpdated").invoke(entity) == null) 
      { 
       entity.getClass().getMethod("setUpdated", Date.class).invoke(entity, 
         GregorianCalendar.getInstance().getTime()); 
      } 

      getEntityManager().getTransaction().begin(); 

      getEntityManager().merge(entity); 

      getEntityManager().flush(); 

      getEntityManager().getTransaction().commit(); 
     } catch (Exception ex) 
     { 
      Logger.getLogger(PersistenceService.class.getName()).log(Level.SEVERE, null, ex); 
      getEntityManager().getTransaction().rollback(); 
     } 
    } 

    public static <T> void remove(T entity) 
    { 
     try 
     { 
      getEntityManager().getTransaction().begin(); 

      getEntityManager().remove(entity); 

      getEntityManager().flush(); 

      getEntityManager().getTransaction().commit(); 

     } catch (Exception ex) 
     { 
      Logger.getLogger(PersistenceService.class.getName()).log(Level.SEVERE, null, ex); 
      getEntityManager().getTransaction().rollback(); 
     } 
    } 

    public static <T> List<T> filter(Class<T> entityClass, String query, SimpleEntry<String, Object>... parameters) 
    { 
     TypedQuery<T> typedQuery = getEntityManager().createQuery(query, entityClass); 

     for (SimpleEntry<String, Object> param : parameters) 
     { 
      typedQuery.setParameter(param.getKey(), param.getValue()); 
     } 

     return typedQuery.getResultList(); 
    } 

    public static <T> T find(Class<T> entityClass, Object id) 
    { 
     T entity = getEntityManager().find(entityClass, id); 

     return entity; 
    } 

    public static <T> List<T> findBy(Class<T> entityClass, String criteria, Object value) 
    { 
     String c = criteria.replaceFirst(criteria.charAt(0) + "", (criteria.charAt(0) + "").toLowerCase()); 

     TypedQuery<T> query = getEntityManager().createNamedQuery(entityClass.getSimpleName() + ".findBy" + criteria, 
       entityClass); 
     query.setParameter(c, value); 

     return query.getResultList(); 
    } 

    public static <T> List<T> findAll(Class<T> entityClass) 
    { 
     CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery(); 
     cq.select(cq.from(entityClass)); 

     return getEntityManager().createQuery(cq).getResultList(); 
    } 

    public static <T> List<T> findRange(Class<T> entityClass, int[] range) 
    { 
     CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery(); 
     cq.select(cq.from(entityClass)); 
     Query q = getEntityManager().createQuery(cq); 
     q.setMaxResults(range[1] - range[0] + 1); 
     q.setFirstResult(range[0]); 

     return q.getResultList(); 
    } 

    public static <T> int count(Class<T> entityClass) 
    { 
     CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery(); 
     Root<T> rt = cq.from(entityClass); 
     cq.select(getEntityManager().getCriteriaBuilder().count(rt)); 
     Query q = getEntityManager().createQuery(cq); 

     return ((Long) q.getSingleResult()).intValue(); 
    } 
} 

Это мой вариант DataSource

package co.peewah.ems.utils; 

import java.beans.PropertyVetoException; 
import java.io.IOException; 
import java.sql.Connection; 
import java.sql.SQLException; 

import org.apache.commons.dbcp.BasicDataSource; 

import com.google.appengine.api.utils.SystemProperty; 

/** 
* 
* @author csacanam 
* 
*/ 
public class DataSource 
{ 

    private static DataSource datasource; 
    private BasicDataSource ds; 

    private DataSource() throws IOException, SQLException, PropertyVetoException 
    { 
     ds = new BasicDataSource(); 


     String mode = ""; 

     if (SystemProperty.environment.value() == SystemProperty.Environment.Value.Development) 
     { 
      mode = "dev."; 
     } 

     String user = System.getProperty("persistence." + mode + "db.user"); 
     String password = System.getProperty("persistence." + mode + "db.password"); 
     String address = System.getProperty("persistence." + mode + "db.url"); 
     String driver = System.getProperty("persistence." + mode + "db.driver"); 

     // Create and configure DBCP DataSource 
     ds.setDriverClassName(driver); 
     ds.setUrl(address); 
     ds.setUsername(user); 
     ds.setPassword(password); 

     ds.setMinIdle(5); 
     ds.setMaxIdle(20); 

     ds.setMaxOpenPreparedStatements(180); 
    } 

    public static DataSource getInstance() throws IOException, SQLException, PropertyVetoException 
    { 
     if(datasource == null) 
     { 
      datasource = new DataSource();  
     } 

     return datasource; 
    } 

    public Connection getConnection() throws SQLException 
    { 
     return this.ds.getConnection(); 
    } 




} 

ответ

0

Добавить autoReconnect=true для подключения MySQL. Самый простой способ, чтобы добавить его само соединение URL:

persistence.db.url=jdbc:mysql://x.x.x.x:3306/y?autoReconnect=true 
0

8-часовой тайм-аут простоя соединения приходит от сервера MySQL, а не клиент, поэтому изменение времени ожидания на клиенте не будет делать. Этот параметр можно настроить на сервере, изменив флаг wait_timeout. Значение по умолчанию - 8 часов.

Вы должны настроить пул соединений для автоматического удаления простоя через некоторое время. В DBCP вы можете включить простаивающее соединение evictor через опцию timeBetweenEvictionRunsMillis.

0

Добавив немного ответа Вадима, на CloudSQL вы можете устанавливать флаги через экземпляр редактирования облачной среды. В Google вы не можете этого сделать, запустив что-то вроде SET GLOBAL wait_timeout=60;, потому что оно не поддерживает привилегии SUPER.

Мне потребовалось некоторое время, чтобы найти это, поэтому я решил, что это может помочь кому-то добавить его здесь.

 Смежные вопросы

  • Нет связанных вопросов^_^