Hibernate查詢緩存中的代理對象與實體類中的Equals方法共造的大坑

因爲項目使用的是Hibernate技術,並設置了二級緩存與查詢緩存,各實體的關聯對象都是以懶加載的方式,因此,在使用HQL查詢後,關聯對象在緩存中保存的是一個代理對象,並非真正的實體對象,以下HQL執行後,t.user的user在緩存中是一個代理對象:
<!-- lang: sql -->
select t, t.user from Book t where t.id = 1024

而User實體類在NetBeans自動生成的equals方法中,有這麼一段:
<!-- lang: java -->
if(getClass() != obj.getClass()){
        return false;
}

因此即便另外一個實體類user2與查詢出來的user1(t.user)有一樣的id,account,name,但user2.equals(user1)老是return false; 由於user2.getClass() = User, 而user1.getClass() = User$javassist_28,因此要想正確比較兩個User對象,有兩點能夠解決:
  1. 將實體類User定義爲final,那麼Hibernate將不能爲user結果生成代理對象,只能是User類,但Hibernate不推薦此舉。
  2. 改變比較方式,直接使用 if (!(obj instanceof User))比較,代理對象user1是User子類的對象。
相關文章
相關標籤/搜索