簡體   English   中英

從數據庫重新加載休眠對象

[英]Hibernate object re-loading from database

我有一個Spring + Hibernate + DBUnit + MySQL應用程序。

步驟如下:

1. I launch the application.
2. A DBUnit test loads data directly into the database (via JDBC).
3. I perform operations and HQL queries to assert the results.


步驟2之后,我立即從控制台查詢數據庫,並確認已正確加載數據。 我的問題是,在第3步中,我通過HQL查詢獲得的對象不包含在第2步中加載的值,而是包含原始值(在第1步及之前的步驟中存在的值)。

在這里閱讀了一些帖子之后,我決定在第3步之前清理會話緩存和二級緩存,以強制Hibernate進行直接數據庫提取。 但是問題仍然存在。

我做錯什么了嗎?


這是我在步驟3中嘗試的腳本:

在啟動應用程序(步驟1)之前,數據庫中的帳戶余額為125。在步驟2中,DBUnit確實將數據庫中的余額更改為10。

   // A break-point here allows me to check through a console that balance at database is cartainly 10.

   // I query the account and print the balance, which is 125.
   List l1 = this.getHibernateTemplate().find("select a from Account a where a.number = ?", parameter);
   Account account1 = (Account) l1.get(0);
   System.out.println("A.- Account 1 balance: " + account1.getBalance());

   // I clear session cache and second-level cache.
   this.getSession().evict(account1);
   this.getSessionFactory().evict(Account.class);       
   this.getSessionFactory().evictQueries();     

   // I repeat the same query, now expecting to force a database fetch. But it still prints 125 and not 10.
   List l2 = this.getHibernateTemplate().find("select a from Account a where a.number = ?", parameter);
   Account account2 = (Account) l2.get(0);
   System.out.println("B.- Account 2 balance: " + account2.getBalance());

我也嘗試過refresh(account1)和session.clear(),但是它們沒有用。

如果這不是正確的解決方案,我願意聽其他人的意見。

謝謝,迭戈。

我認為您正在看到此行為,因為您的事務是在REPEATABLE_READ中配置的。 這意味着Hibernate保證同一事務中的兩次讀取將始終返回相同的結果。 由於隔離級別優先於緩存逐出,因此緩存逐出不會產生任何可見效果。

有一種方法可以解決此問題:
將事務隔離級別聲明為READ_UNCOMMITTED或READ_COMMITTED。 您可能會遇到著名的,如果你使用的是標准方言“標准JPA不支持自定義隔離級別的”異常。 在這種情況下,您可以應用以下解決方法:
Spring 3.3: http//amitstechblog.wordpress.com/2011/05/31/supporting-custom-isolation-levels-with-jpa/
3.2版春季: http//shahzad-mughal.blogspot.com/2012/04/spring-jpa-hibernate-support-for-custom.html

我不了解休眠,但這是使用JPA進行的shuold:

public <T> T load(Class<T> entityClass, Object pk)
{
    Map<String, Object> props = new HashMap<>();
    props.put("javax.persistence.cache.retrieveMode", CacheRetrieveMode.BYPASS);

    return getEntityManager().find(entityClass, pk, props);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM