2012-10-30 58 views
1

我想了解我看到的反直覺Hibernate行爲。我一直認爲「flush」意味着hibernate具有必須寫入數據庫的內存中的數據結構。這不是我所看到的。爲什麼在選擇查詢(EmptyInterceptor)上刷新hibernate?

我創建了以下攔截器:

public class FeedInterceptor extends EmptyInterceptor 
{ 
    @Override 
    public void postFlush(Iterator entities) 
    { 
      System.out.println("postFlush");   
    } 
} 

在我的ApplicationContext中註冊它

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
    <property name="entityInterceptor"> 
     <bean class="interceptor.FeedInterceptor"/> 
    </property> 
</bean> 

但是,夠奇怪的,我看「postFlush」寫入控制檯從檢索到的每一行DB從我的DAO:

Session session = sessionFactory.getCurrentSession(); 
Query query = session.createQuery("from Feed feed"); 
query.list(); 

這是爲什麼?

回答

3

假設休眠不會刷新會話,那麼你可以有以下情況:

Person p = new Person(); 
p.setName("Pomario"); 
dao.create(p); 
Person pomario = dao.findPersonByName("Pomario") 
//pomario is null? 

當名字找到一個人,休眠問題select語句到數據庫。如果它先不發送前面的語句,那麼返回的結果可能與會話中以前做過的更改不一致,這裏dababase還沒有收到create語句,所以它返回一個空的結果集。

+1

我期望剛創建的Person存在某種形式的緩存(第一級/第二級),並且知道在對數據庫執行findPersonByName()之前必須刷新髒數據,與findPersonByName()的每次調用都是相反的,這與我在query.list()中看到的情況相反。可以請評論一下嗎? – Pomario

+0

你是對的,它可以檢測到一些unsave變更必須刷新到數據庫,然後只在需要時刷新休眠會話。我不明白你的問題。在發出select語句之前或之後(例如,您可以設置show_sql參數)之後,知道flush是否會發生很有意思。如果您在語句後看到控制檯中出現「postFlush」,那麼可能意味着「flush」操作包括向數據庫發出所有掛起的語句,最後一個語句是運行查詢時需要執行的select語句。 list()' – Alban

+0

它已經有了這個優化。如果您堅持或修改Person,並執行僅使用Foo實體的查詢,則Hibernate在執行查詢之前不會刷新。 –