2010-05-19 2 views
1

Это проблема, которую я видел во всем Интернете. Я подниму его снова, так как до сих пор у меня нет исправления для того же самого.Ошибка соединения с Hibernate-mysql-c3p0

I am using hibernate 3. mysql 5 and latest c3p0 jar. I am getting a broken pipe exception. Following is my hibernate.cfg file. 

com.mysql.jdbc.Driver org.hibernate.dialect.MySQLDialect

<property name="hibernate.show_sql">true</property> 
    <property name="hibernate.use_sql_comments">true</property> 
    <property name="hibernate.current_session_context_class">thread</property> 
    <property name="connection.autoReconnect">true</property> 
    <property name="connection.autoReconnectForPools">true</property> 
    <property name="connection.is-connection-validation-required">true</property> 

    <!--<property name="c3p0.min_size">5</property> 
    <property name="c3p0.max_size">20</property> 
    <property name="c3p0.timeout">1800</property> 
    <property name="c3p0.max_statements">50</property> 


    --><property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider 
</property> 
    <property name="hibernate.c3p0.acquireRetryAttempts">30</property> 
    <property name="hibernate.c3p0.acquireIncrement">5</property> 
    <property name="hibernate.c3p0.automaticTestTable">C3P0TestTable</property> 

    <property name="hibernate.c3p0.idleConnectionTestPeriod">36000</property> 

    <property name="hibernate.c3p0.initialPoolSize">20</property> 
    <property name="hibernate.c3p0.maxPoolSize">100</property> 
    <property name="hibernate.c3p0.maxIdleTime">1200</property> 
    <property name="hibernate.c3p0.maxStatements">50</property> 
    <property name="hibernate.c3p0.minPoolSize">10</property>--> 

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

общественного класса HibernateUtil {

private static Logger log = Logger.getLogger(HibernateUtil.class); 
//private static Log log = LogFactory.getLog(HibernateUtil.class); 

private static Configuration configuration; 
private static SessionFactory sessionFactory; 

static { 
    // Create the initial SessionFactory from the default configuration files 
    try { 

     log.debug("Initializing Hibernate"); 

     // Read hibernate.properties, if present 
     configuration = new Configuration(); 
     // Use annotations: configuration = new AnnotationConfiguration(); 

     // Read hibernate.cfg.xml (has to be present) 
     configuration.configure(); 

     // Build and store (either in JNDI or static variable) 
     rebuildSessionFactory(configuration); 

     log.debug("Hibernate initialized, call HibernateUtil.getSessionFactory()"); 
    } catch (Throwable ex) { 
     // We have to catch Throwable, otherwise we will miss 
     // NoClassDefFoundError and other subclasses of Error 
     log.error("Building SessionFactory failed.", ex); 
     throw new ExceptionInInitializerError(ex); 
    } 
} 

/** 
* Returns the Hibernate configuration that was used to build the SessionFactory. 
* 
* @return Configuration 
*/ 
public static Configuration getConfiguration() { 
    return configuration; 
} 

/** 
* Returns the global SessionFactory either from a static variable or a JNDI lookup. 
* 
* @return SessionFactory 
*/ 
public static SessionFactory getSessionFactory() { 
    String sfName = configuration.getProperty(Environment.SESSION_FACTORY_NAME); 
    System.out.println("Current s name is "+sfName); 
    if (sfName != null) { 
     System.out.println("Looking up SessionFactory in JNDI"); 
     log.debug("Looking up SessionFactory in JNDI"); 
     try { 
      System.out.println("Returning new sssion factory"); 
      return (SessionFactory) new InitialContext().lookup(sfName); 
     } catch (NamingException ex) { 
      throw new RuntimeException(ex); 
     } 
    } else if (sessionFactory == null) { 
     System.out.println("calling rebuild session factory now"); 
     rebuildSessionFactory(); 
    } 
    return sessionFactory; 
} 

/** 
* Closes the current SessionFactory and releases all resources. 
* <p> 
* The only other method that can be called on HibernateUtil 
* after this one is rebuildSessionFactory(Configuration). 
*/ 
public static void shutdown() { 
    log.debug("Shutting down Hibernate"); 
    // Close caches and connection pools 
    getSessionFactory().close(); 

    // Clear static variables 
    sessionFactory = null; 
} 


/** 
* Rebuild the SessionFactory with the static Configuration. 
* <p> 
* Note that this method should only be used with static SessionFactory 
* management, not with JNDI or any other external registry. This method also closes 
* the old static variable SessionFactory before, if it is still open. 
*/ 
public static void rebuildSessionFactory() { 
    log.debug("Using current Configuration to rebuild SessionFactory"); 
    rebuildSessionFactory(configuration); 
} 

/** 
* Rebuild the SessionFactory with the given Hibernate Configuration. 
* <p> 
* HibernateUtil does not configure() the given Configuration object, 
* it directly calls buildSessionFactory(). This method also closes 
* the old static variable SessionFactory before, if it is still open. 
* 
* @param cfg 
*/ 
public static void rebuildSessionFactory(Configuration cfg) { 
    log.debug("Rebuilding the SessionFactory from given Configuration"); 
    if (sessionFactory != null && !sessionFactory.isClosed()) 
     sessionFactory.close(); 
    if (cfg.getProperty(Environment.SESSION_FACTORY_NAME) != null) { 
     log.debug("Managing SessionFactory in JNDI"); 
     cfg.buildSessionFactory(); 
    } else { 
     log.debug("Holding SessionFactory in static variable"); 
     sessionFactory = cfg.buildSessionFactory(); 
    } 
    configuration = cfg; 
} 

}

Выше мой код для сессии завода. И у меня есть только операции выбора.

И ниже - метод, который чаще всего используется для выполнения моих выбранных запросов. Одна сложная вещь, которую я не понимаю, в моем методе findById, я использую эту строку кода getSession(). BeginTransaction(); без чего он дает мне ошибку, говоря, что это не может произойти без транзакции. Но нигде я не закрываю эту транзакцию. И не существует метода закрытия транзакции, кроме фиксации или откат (насколько я знаю), которые неприменимы для операторов select.

общественного Т findById (ID ID, логический замок) бросает HibernateException, DAOException { log.debug ("findNyId вызывается с ID =" + ID + "и замок =" + замок); T объект; getSession(). BeginTransaction();

if (lock) 
     entity = (T) getSession().load(getPersistentClass(), id, LockMode.UPGRADE); 
    else 
     entity = (T) getSession().load(getPersistentClass(), id); 

    return entity; 
} 

Может кто-нибудь предложить, что я могу сделать? Я опробовал почти все решения, доступные через googling, на stackoverlow или на форумах с гибернацией безрезультатно. (И увеличение wait_timeout на mysql не является допустимым вариантом в моем случае).

ответ

1

Я понимаю, что MySQL может аннулировать соединения после «n» часов без использования (см. here) для справки.

Итак, вы можете настроить C3P0 для проверки соединения, прежде чем давать его вам (клиенту)? Или сконфигурируйте C3P0 для выключения соединений через определенное время? См. this link для получения дополнительной информации.

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