2010-05-19 74 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語句。

public T findById(ID id,boolean lock)throws HibernateException,DAOException log.debug(「findNyId用ID =」+ id +「調用並且lock =」+ lock); T實體; getSession()。beginTransaction();

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

    return entity; 
} 

任何人都可以請建議我能做些什麼?我嘗試了幾乎所有可用的解決方案,通過googling,stackoverlow或hibernate論壇都無濟於事。 (在我的情況下,增加mysql上的wait_timeout不是一個有效的選項)。

回答

1

據我所知,MySQL可以在連續使用n小時之後使連接無效(請參閱here)以供參考。

那麼你能配置C3P0驗證一個連接,然後再給你(客戶端)嗎?或者在一段時間後配置C3P0超時連接?有關更多信息,請參閱this link