4

私はmySQLでHibernate/JPAを使用していますが、従来の理由により、ある時点でcreateNativeQueryを使用しています。アプリケーションは、同じデータベースを使用する異なるサーバーで動作するため、キャッシュをまったく行わず、常に最新の結果を表示する必要があります。データベースエディタで値を手動で変更して他のサーバーをシミュレートしますが、変更後は常に古い結果になります。

私が知る限り、第 2 レベルのキャッシュを無効にし (ORM オブジェクトを使用しないため、あまり重要ではありません)、第 1 レベルのキャッシュを clear() し、mysql クエリのキャッシュを無効にする必要があります (データベース レベルで既に行われています)。どこで失敗したり、何を忘れたりしますか? それは私を夢中にさせます。

init(): サーブレットの開始

    entityFactory = Persistence.createEntityManagerFactory("persistence-id");

getEntityManager(): 各リクエストの開始

    destroyEntityManager(); // just in case
    entityFactory.getCache().evictAll();
    entityManager = entityFactory.createEntityManager();
    entityManager.setProperty("javax.persistence.cache.storeMode",
            CacheStoreMode.BYPASS);
    entityManager.clear(); // just in case

destroyEntityManager(): 各リクエストの終わり

    if (entityManager != null) {
        if (entityManager.getTransaction().isActive()) {
            entityManager.flush();
            entityManager.getTransaction().commit();
        }
        entityManager.clear();
        if (entityManager.isOpen()) {
            entityManager.close();
        }
        entityManager = null;
    }

destroy(): サーブレットの終わり

    destroyEntityManager();
    if (entityFactory != null) {
        entityFactory.close();
    }

persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/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_1_0.xsd" version="1.0">
<persistence-unit name="WallMountBackOffice-PU">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>...</class>
    <class>...</class>
    <properties>
        <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
        <property name="hibernate.connection.url" value="jdbc:mysql://localhost/ourschema" />
        <property name="hibernate.connection.username" value="root" />
        <property name="hibernate.connection.password" value="" />
        <property name="hibernate.connection.pool_size" value="10" />
        <property name="hibernate.connection.autocommit" value="false" />
        <property name="hibernate.connection.release_mode" value="on_close" />
        <property name="dialect" value="org.hibernate.dialect.MySQLDialect" />
        <property name="hibernate.cache.use_second_level_cache"
            value="false" />
        <property name="hibernate.cache.use_query_cache" value="false" />
        <property name="javax.persistence.sharedCache.mode" value="NONE" />
        <property name="org.hibernate.cacheable" value="false" />
    </properties>
</persistence-unit>

「select ...」を実行するコード:

    ...
    Query jpaQuery = entityManager.createQuery(query);
    entityManager.getTransaction().begin();
    jpaQuery.executeUpdate();
    entityManager.getTransaction().commit();
4

2 に答える 2

3

最初の行に誤りがあります。次のように、「REFRESH」ではなく「BYPASS」でなければなりません。

query.setHint("javax.persistence.cache.retrieveMode", "BYPASS");

また、文字列リテラルの代わりに JPA 列挙型を使用することが推奨されるため、次のようになります。

query.setHint(QueryHints.CACHE_RETRIEVE_MODE, CacheRetrieveMode.BYPASS);
query.setHint(QueryHints.CACHE_STORE_MODE, CacheStoreMode.REFRESH); 
于 2014-11-09T09:59:56.527 に答える
1

setHint() storeModeまたはretrieveModeメソッドを使用できます。レコードを取得しようとしている場合は、 with を使用retrieveModeBYPASSます。

休止状態の場合

query.setHint("javax.persistence.cache.storeMode", "REFRESH");

query.setHint("javax.persistence.cache.retrieveMode", "REFRESH"); 

EclipseLink の場合。

query.setHint("javax.persistence.cache.storeMode", "REFRESH"); 

query.setHint("javax.persistence.cache.retrieveMode", "REFRESH"); 

JPA 2.0 仕様

public enum CacheRetrieveMode {

    /**
     * Read entity data from the cache: this is
     * the default behavior.
     */
    USE,

    /**
     * Bypass the cache: get data directly from
     * the database.
     */
    BYPASS
}

public enum CacheStoreMode {

    /**
     * Insert/update entity data into cache when read
     * from database and when committed into database:
     * this is the default behavior. Does not force refresh
     * of already cached items when reading from database.
     */
    USE,

    /**
     * Don't insert into cache.
     */
    BYPASS,

    /**
     * Insert/update entity data into cache when read
     * from database and when committed into database:
     * Forces refresh of cache for items read from database.
     */
    REFRESH
}   
于 2012-10-29T17:52:57.080 に答える