在服务器启动时跳过持久性单元验证

时间:2016-05-18 01:21:43

标签: hibernate jpa tomee

我有一个persistence.xml,我需要连接到5个不同的数据库,所以我定义了5个不同的持久性单元。我当前的persistence.xml看起来如下所示

<?xml version="1.0" encoding="UTF-8" ?>
<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"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="ec2Production" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
    <properties>
        <property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider" />
        <property name="hibernate.show_sql" value="false" />
        <property name="hibernate.format_sql" value="false" />

        <property name="hibernate.connection.driver_class"  value="com.mysql.jdbc.Driver" />
        <property name="hibernate.connection.url" value="jdbc:mysql://xxxxx:3306/xxxxx?autoReconnect=true" />
        <property name="hibernate.connection.username" value="xxxxxx" />
        <property name="hibernate.connection.password" value="xxxxx" />

        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
        <property name="hibernate.c3p0.acquire_increment" value="1"/>
        <property name="hibernate.c3p0.max_size" value="15"/>
        <!-- it must be set to LESS than the wait_timout setting for the mysql server (this setting defaults to 28800 secs (8 hours)) -->
        <property name="hibernate.c3p0.idle_test_period" value="28680" />
        <property name="hibernate.c3p0.preferredTestQuery" value="select 1;" />
        <property name="hibernate.c3p0.timeout" value="60000"/>
        <property name="hibernate.connection.zeroDateTimeBehavior" value="convertToNull"/>
        <property name="hibernate.c3p0.debugUnreturnedConnectionStackTraces " value="true"/>
        <property name="debugUnreturnedConnectionStackTraces " value="true"/>
        <property name="hibernate.cache.use_second_level_cache" value="true" />
        <property name="hibernate.cache.use_query_cache" value="true" />
        <property name="hibernate.cache.region.factory_class" value="com.mc.hibernate.memcached.MemcachedRegionFactory" />
        <property name="hibernate.memcached.operationTimeout" value = "40000"/>
        <property name="hibernate.memcached.connectionFactory" value = "KetamaConnectionFactory"/>
        <property name="hibernate.memcached.hashAlgorithm" value = "HashAlgorithm.FNV1_64_HASH"/>
        <property name="hibernate.memcached.servers" value = "xxxxxxxxxx:11211"/>

        <property name="hibernate.cache.region_prefix" value=""/>
    </properties>
</persistence-unit>

<persistence-unit name="ec2Marketing" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
    <properties>
        <property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider" />
        <property name="hibernate.show_sql" value="false" />
        <property name="hibernate.format_sql" value="false" />

        <property name="hibernate.connection.driver_class"  value="com.mysql.jdbc.Driver" />
        <property name="hibernate.connection.url" value="jdbc:mysql://xxxxxx:3306/xxxxxx?autoReconnect=true" />
        <property name="hibernate.connection.username" value="xxxxx" />
        <property name="hibernate.connection.password" value="xxxxxxx" />

        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
        <property name="hibernate.c3p0.acquire_increment" value="1"/>
        <property name="hibernate.c3p0.max_size" value="40"/>
        <property name="hibernate.c3p0.idle_test_period" value="28680" />
        <property name="hibernate.c3p0.preferredTestQuery" value="select 1;" />
        <property name="hibernate.c3p0.timeout" value="60000"/>
        <property name="hibernate.connection.zeroDateTimeBehavior" value="convertToNull"/>
        <property name="hibernate.c3p0.debugUnreturnedConnectionStackTraces " value="true"/>
        <property name="debugUnreturnedConnectionStackTraces " value="true"/>
        <property name="hibernate.cache.use_second_level_cache" value="true" />
        <property name="hibernate.cache.use_query_cache" value="true" />
        <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory" />
        <property name="hibernate.cache.region.factory_class" value="com.mc.hibernate.memcached.MemcachedRegionFactory" />
        <property name="hibernate.memcached.operationTimeout" value = "40000"/>
        <property name="hibernate.memcached.connectionFactory" value = "KetamaConnectionFactory"/>
        <property name="hibernate.memcached.hashAlgorithm" value = "HashAlgorithm.FNV1_64_HASH"/>
        <property name="hibernate.memcached.servers" value = "xxxxxx:11211"/>

        <property name="hibernate.cache.region_prefix" value=""/>
    </properties>
</persistence-unit>

一切正常,但是当我启动服务器时,它会尝试连接到所有持久性单元,因此服务器启动变得非常慢。在我的大多数情况下,我很少需要连接到所有持久性单元。

我希望通过跳过每个持久性单元的验证来快速启动服务器启动。

我正在使用hibernate4,使用tomee 1.7.4作为服务器。

以下是在tomee服务器上生成的日志片段

2016-05-19 06:11:31 http-bio-8080-exec-2 INFO C3P0Registry - 初始化c3p0-0.9.2.1 [建于2013年3月20日10:47:27 +0000;调试?真正;追踪:10] 2016-05-19 06:11:31 http-bio-8080-exec-2 INFO AbstractPoolBackedDataSource - 初始化c3p0池... com.mchange.v2.c3p0.PoolBackedDataSource@b7e616dd [connectionPoolDataSource - &gt; com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@ecdf85aa [acquireIncrement - &gt; 1,acquireRetryAttempts - &gt; 30,acquireRetryDelay - &gt; 1000,autoCommitOnClose - &gt; false,automaticTestTable - &gt; null,breakAfterAcquireFailure - &gt; false,checkoutTimeout - &gt; 0,connectionCustomizerClassName - &gt; null,connectionTesterClassName - &gt; com.mchange.v2.c3p0.impl.DefaultConnectionTester,debugUnreturnedConnectionStackTraces - &gt; true,factoryClassLocation - &gt; null,forceIgnoreUnresolvedTransactions - &gt; false,identityToken - &gt; 1hge1369g1j2d3s55wlq0u | 77b47a17,idleConnectionTestPeriod - &gt; 28680,initialPoolSize - &gt; 3,maxAdministrativeTaskTime - &gt; 0,maxConnectionAge - &gt; 0,maxIdleTime - &gt; 60000,maxIdleTimeExcessConnections - &gt; 0,maxPoolSize - &gt; 40,maxStatements - &gt; 0,maxStatementsPerConnection - &gt; 0,minPoolSize - &gt; 3,nestedDataSource - &gt; com.mchange.v2.c3p0.DriverManagerDataSource@668bb235 [description - &gt; null,driverClass - &gt; null,factoryClassLocation - &gt; null,identityToken - &gt; 1hge1369g1j2d3s55wlq0u | 687e1712,jdbcUrl - &gt; jdbc:mysql:// localhost:3306 / xxxxx?autoReconnect = true,properties - &gt; {user = ******,password = ******,autocommit = true,zeroDateTimeBehavior = convertToNull,release_mode = auto}],preferredTestQuery - &gt;选择1;,propertyCycle - &gt; 0,statementCacheNumDeferredCloseThreads - &gt; 0,testConnectionOnCheckin - &gt; false,testConnectionOnCheckout - &gt; false,unreturnedConnectionTimeout - &gt; 0,usesTraditionalReflectiveProxies - &gt;假; userOverrides:{}],dataSourceName - &gt; null,factoryClassLocation - &gt; null,identityToken - &gt; 1hge1369g1j2d3s55wlq0u | 65f14317,numHelperThreads - &gt; 3]

这是为每个持久性单元生成的日志,稍后当第一次为持久性单元发生任何连接时,我会在我的日志文件中再次看到此日志。

由于

1 个答案:

答案 0 :(得分:0)

我认为应用程序启动缓慢的主要原因是它的编写方式。我有很多应用程序有5-10个数据源,而TomEE启动只需几秒钟。

主要问题是您不允许容器管理您的任何对象。容器的设计是为了有效地实现这一目标,而Hibernate在外部世界中发生的事情的范围有限。这里有几个起点:

<persistence-unit transaction-type="RESOURCE_LOCAL"> 意味着您手动管理PU的生命周期。我会高度提出反对意见。而是优化应用程序容器以有效地池化这些对象。切换到<persistence-unit transaction-type="JTA">并让容器管理对象的生命周期,它的设计目标。注入一个持久性单元的实例,如下所示:@PersistenceContext private EntityManager em;

其次,您在应用程序内定义数据源和池。我会高度推荐这个。同样,应用程序容器的要点是有效地池化和管理对象的生命周期。要解决此问题,请在tomee.xml中定义一个如下所示的数据源:

<Resource id="jdbc/moviesdb" type="DataSource">
  JdbcDriver=com.mysql.jdbc.Driver
  JdbcUrl=jdbc:mysql:localhost:3306/moviesdb
  UserName=sa
  Password=secret
  JtaManaged=true
  ValidationQuery=SELECT 1
  TestOnBorrow=true
</Resource>

然后删除所有这些:

   <property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider" />
        <property name="hibernate.show_sql" value="false" />
        <property name="hibernate.format_sql" value="false" />

        <property name="hibernate.connection.driver_class"  value="com.mysql.jdbc.Driver" />
        <property name="hibernate.connection.url" value="jdbc:mysql://xxxxx:3306/xxxxx?autoReconnect=true" />
        <property name="hibernate.connection.username" value="xxxxxx" />
        <property name="hibernate.connection.password" value="xxxxx" />

        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
        <property name="hibernate.c3p0.acquire_increment" value="1"/>
        <property name="hibernate.c3p0.max_size" value="15"/>
        <!-- it must be set to LESS than the wait_timout setting for the mysql server (this setting defaults to 28800 secs (8 hours)) -->
        <property name="hibernate.c3p0.idle_test_period" value="28680" />
        <property name="hibernate.c3p0.preferredTestQuery" value="select 1;" />
        <property name="hibernate.c3p0.timeout" value="60000"/>
        <property name="hibernate.connection.zeroDateTimeBehavior" value="convertToNull"/>
        <property name="hibernate.c3p0.debugUnreturnedConnectionStackTraces " value="true"/>
        <property name="debugUnreturnedConnectionStackTraces " value="true"/>

并将其替换为:

<jta-data-source>jdbc/moviesdb</jta-data-source>

最后,如果不完全有必要使用Hibernate,我建议切换到EclipseLink,它在内存,CPU和性能方面占用的空间要小得多。

欢呼,祝你好运

参考文献:

http://tomee.apache.org/containers-and-resources.html#ContainersandResources-Resources