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

Hibernate 在服务器启动时跳过持久性单元验证,hibernate,jpa,apache-tomee,Hibernate,Jpa,Apache 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

我有一个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>

org.hibernate.ejb.HibernatePersistence
启用\u选择性
org.hibernate.ejb.HibernatePersistence
启用\u选择性

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

我想通过跳过每个持久化单元的验证,使服务器快速启动

我正在使用hibernate4,以Tomee1.7.4作为服务器

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

2016-05-19 06:11:31 http-bio-8080-exec-2信息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信息抽象池备份数据源-初始化c3p0池。。。com.mchange.v2.c3p0。PoolBackedDataSource@b7e616dd[connectionPoolDataSource->com.mchange.v2.c3p0。WrapperConnectionPoolDataSource@ecdf85aa [acquireIncrement->1,AcquireEntryAttributes->30,AcquireEntryDisplay->1000,自动提交关闭->false,自动测试表->null,breakAfterAcquireFailure->false,签出超时->0,connectionCustomizerClassName->null,ConnectionTestClassName->com.mchange.v2.c3p0.impl.DefaultConnectionTester,DebuggeunReturnedConnectionsTackTraces->true,factoryClassLocation->null,ForceIgnoreUnsolvedTransactions->false,identityToken->1hge1369g1j2d3s55wlq0u | 77b47a17,idleConnectionTestPeriod->28680,initialPoolSize->3,maxAdministrativeTaskTime->0,maxConnectionAge->0,maxIdleTime->60000,maxIdleTimeExcessConnections->->0,maxPoolSize->40,maxStatements->0,maxStatementsPerConnection->0,minPoolSize->3,nestedDataSource->com.mchange.v2.c3p0。DriverManagerDataSource@668bb235[description->null,driverClass->null,factoryClassLocation->null,identityToken->1hge1369g1j2d3s55wlq0u | 687e1712,jdbcUrl->jdbc:mysql://localhost:3306/xxxxx?autoReconnect=true,物业->{user=*******,password=****,autocommit=true,zeroDateTimeBehavior=convertToNull,release\u mode=auto}],preferredTestQuery->select 1;,propertyCycle->0,语句CacheNumDeferredCloseThreads->0,testConnectionOnCheckin->false,testConnectionOnCheckout->false,unreturnedConnectionTimeout->0,UseStraditionalReflectionProxies->false;用户覆盖:{}],dataSourceName->null,factoryClassLocation->null,identityToken->1hge1369g1j2d3s55wlq0u | 65f14317,numHelperThreads->3]

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


谢谢

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

主要问题是您不允许容器管理您的任何对象。容器的设计是为了有效地管理对象,而Hibernate对外部世界发生的事情的范围有限。以下是一些出发点:

表示您正在手动管理PU的生命周期。我强烈建议您不要这样做。相反,应用程序容器经过优化以高效地汇集这些对象。切换到
,让容器管理对象的生命周期,这就是它的设计目的。注入一个持久性单元的实例,如下所示:
@PersistenceContext私有实体管理器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>

JdbcDriver=com.mysql.jdbc.Driver
JdbcUrl=jdbc:mysql:localhost:3306/moviesdb
用户名=sa
密码=秘密
JtaManaged=true
ValidationQuery=选择1
TestOnBorrow=true
然后删除所有这些:

   <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>
jdbc/moviesdb
最后,如果不完全需要使用Hibernate,我建议切换到EclipseLink,它在内存、CPU和性能方面占用的空间要小得多

干杯,祝你好运

参考资料:


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

主要问题是您不允许容器管理您的任何对象。容器的设计是为了有效地管理对象,而Hibernate对外部世界发生的事情的范围有限。以下是一些出发点:

表示您正在手动管理PU的生命周期。我强烈建议您不要这样做。相反,应用程序容器经过优化,可以高效地将这些对象汇集在一起。切换到
,让容器管理对象的生命周期,然后