1

我试图阻止这种记录

从服务器成功接收到的最后一个数据包是 10,255 毫秒前。最后一个成功发送到服务器的数据包是 0 毫秒前。

我已经在persistence.xml中设置了自动重新连接的连接url

我想要的是会有一个连接池,每分钟或每小时检查一次连接,以便连接仍然存在。Hibernate与 c3po 具有此功能。喜欢ff。

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

  <property name="hibernate.c3p0.numHelperThreads">5</property>
  <property name="hibernate.c3p0.maxAdministrativeTaskTime">5</property>
  <property name="statementCacheNumDeferredCloseThreads">1</property>

  <property name="hibernate.c3p0.validate">true</property>
  <property name="hibernate.c3p0.preferredTestQuery">select 1;</property>
  <property name="hibernate.c3p0.testConnectionOnCheckout">true</property>

  <property name="hibernate.c3p0.automaticTestTable">C3P0</property>

无论如何我可以在eclipselink中做到这一点吗?

4

2 回答 2

2

2014 年 11 月 18 日更新

我发现我最初提供的答案有一些问题!检索到的密码是通过eclipselink加密的,所以我们不能直接使用。我们可以在这里硬编码我们的密码,但这可能不太好。我发现一个更好的方法是在创建实体管理器工厂时传递一个自定义 DataSource 对象。

additionalProperties.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, dataSource);
emf = Persistence.createEntityManagerFactory(persistUnit, additionalProperties);

请在此处查看示例代码:https ://github.com/jiakuan/wise-persist/blob/master/src/main/java/org/wisepersist/EntityManagerFactoryProvider.java

原答案:

我遇到了同样的问题,我刚刚发现我可以通过创建自定义 SessionCustomizer 将 bonecp 数据源(c3p0 应该类似)与 eclipselink 一起使用。像这样的东西:

public class JpaSessionCustomizer implements SessionCustomizer {

  private static final Logger log = LoggerFactory.getLogger(JpaSessionCustomizer.class);

  @Override
  public void customize(Session session) throws Exception {
    DatabaseLogin databaseLogin = session.getLogin();

    String jdbcDriver = databaseLogin.getDriverClassName();
    String jdbcUrl = databaseLogin.getDatabaseURL();
    String username = databaseLogin.getUserName();
    // WARNING: databaseLogin.getPassword() is encrypted,
    // which cannot be used directly here
    String password = "please use hard-coded password here";
    log.debug("jdbcDriver={}, jdbcUrl={}, username={}, password={}",
              jdbcDriver, jdbcUrl, username, password);

    BoneCPDataSource dataSource = buildDataSource(jdbcDriver, jdbcUrl, username, password);
    databaseLogin.setConnector(new JNDIConnector(dataSource));
  }

  private BoneCPDataSource buildDataSource(String jdbcDriver,
                                           String jdbcUrl,
                                           String username,
                                           String password) {
    BoneCPDataSource dataSource = new BoneCPDataSource();
    dataSource.setDriverClass(jdbcDriver); // Loads the JDBC driver
    dataSource.setJdbcUrl(jdbcUrl);
    dataSource.setUsername(username);
    dataSource.setPassword(password);

    dataSource.setConnectionTimeout(15, TimeUnit.SECONDS);
    dataSource.setAcquireRetryAttempts(10);

    dataSource.setConnectionTestStatement("SELECT 1");
    dataSource.setIdleConnectionTestPeriodInSeconds(30);

    dataSource.setPartitionCount(2);
    dataSource.setMinConnectionsPerPartition(5);
    dataSource.setMaxConnectionsPerPartition(10);

    dataSource.setDisableConnectionTracking(true);
    return dataSource;
  }
}

如果您想在 eclipselink 中使用 c3p0,也许您只需要在 buildDataSource 方法中使用本页 ( http://www.mchange.com/projects/c3p0/#using_combopooleddatasource ) 中提到的代码。

一些有用的链接:

于 2014-05-18T10:40:41.217 回答
0

关于:警告:databaseLogin.getPassword() 已加密;

您可以使用以下内容:

Map<Object, Object> props = session.getProperties();
...
dataSource.setPassword((String) props.get("javax.persistence.jdbc.password"));
...

问候!!

于 2017-12-19T14:57:02.153 回答