2012-10-29 57 views
4

我正在使用Hibernate/JPA與mySQL,並且由於遺留原因createNativeQuery在一個點上。該應用程序可以與使用相同數據庫的不同服務器一起工作,因此它不應該緩存,而是始終顯示最新的結果。我通過在數據庫編輯器中手動更改一個值來模擬其他服務器,但在更改後它總是會給出舊的結果。Hibernate JPA + mysql:無法在createNativeQuery中禁用緩存

據我所知,我應該禁用任何二級緩存(不是很重要,因爲我沒有使用任何ORM對象),clear()任何一級緩存,並禁用mysql查詢緩存(已經完成數據庫水平)。我在哪裏失敗,或者我忘了什麼?它讓我瘋狂。

的init():該servlet

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; 
    } 

破壞():servlet結束

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> 

它執行的代碼 '選擇...':

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

回答

1

您可以使用setHint()storeModeretrieveMode方法。如果您嘗試檢索記錄,請使用retrieveMode並使用BYPASS

對於休眠

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 
} 
1

在第一行中,有一個錯誤,它必須是 「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);