【问题标题】:JPA does not honours caching while creating entity manager factory dynamicallyJPA 在动态创建实体管理器工厂时不支持缓存
【发布时间】:2016-05-12 12:44:18
【问题描述】:

我正在使用 hibernate 4.2 并使用 tomee 1.7.4 在 J2ee6 上工作。我需要编写多租户代码,可以按需连接各种数据库。我尝试通过在 persistence.xml 中创建多个持久性单元来做到这一点,但在服务器启动期间,tomee 会尝试验证与所有持久性单元的连接(在测试期间它们可能都不可用)。

我试图找到一些设置来告诉 tomee 在启动时跳过连接验证,但找不到。所以我没有从持久化单元创建实体管理器,而是开始使用该函数

javax.persistence.Persistence.createEntityManagerFactory(String persistenceUnitName, Map properties)

而我的持久化 xml 没有任何属性。这帮助我解决了这个问题,但是当我转移到这个模型时,我的缓存停止工作,它以前可以工作。

任何人都可以提出一些方法,让我可以让 tomee 在启动时跳过验证持久性单元,或者我可以用我找到的另一种方式启用缓存。

我之前的 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="localDB" 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://localhost:3306/xxxxxx?autoReconnect=true" />
        <property name="hibernate.connection.username" value="xxxxx" />
        <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="40"/>
        <!-- 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 = "xxxxx:xxxx"/>

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

<persistence-unit name="production" 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/thewalkindb?autoReconnect=true" />
        <property name="hibernate.connection.username" value="xxxx" />
        <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 = "xxxxxxxx"/>

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

这适用于缓存,但它不能让我灵活地在 tomee 启动时跳过验证

我的新持久性 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="localDB" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
    <properties></properties>
</persistence-unit>

<persistence-unit name="production" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
    <properties>
    </properties>
</persistence-unit>

我正在填充地图中的所有属性并调用该函数 javax.persistence.Persistence.createEntityManagerFactory(String persistenceUnitName, Map properties),但不知何故它不尊重缓存。

【问题讨论】:

    标签: java hibernate jpa caching apache-tomee


    【解决方案1】:

    我没有得到验证和缓存之间的联系。如果您对实体管理器租户进行外观处理,则您知道每个实体管理器都只有缓存,这意味着您不会检查本地缓存中的生产持久性单元。

    如果您想要一个实体管理器 - =您将在此模式下获得一个 JPA 缓存,它将合并本地和生产 - 您可以使用动态路由:http://tomee.apache.org/examples-trunk/dynamic-datasource-routing/README.html 而不是动态持久性单元。

    【讨论】:

    • 我的persistence.xml 有3 个持久化单元,有3 个不同的jdbc url,在我的开发过程中,我无法连接到prod,在prod 过程中,我无法连接到开发服务器。目前所有的 url 都在持久性 xml 中定义,但我只在代码中使用相关的持久性单元。 Tomee 在启动期间尝试连接到所有持久性单元,因此每次我都必须更改持久性 xml。我的主要目标是拥有相同的持久性 xml,但默认情况下,tomee 不应连接到每一个
    • 在 conf/system.properties 中可以设置:PERSISTENCEUNIT.theUnitName.thePropertyName=thePropertyValue
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-09
    • 2013-05-17
    • 2013-06-01
    相关资源
    最近更新 更多