2011-09-01 58 views
10

我們使用Hibernate Envers並具有以下情況:休眠Envers和「Javassist進行強化失敗」異常

BusinessObjectType和類Identity與參考BusinessObjectType

@Entity 
@Table(name = "ID_IDENTITY") 
@Audited 
public class Identity { 

    @ManyToOne 
    @JoinColumn(name = "BO_TYPE_ID") 
    @IndexColumn(name = "INDEX_BO_BO_TYPE") 
    private BusinessObjectType businessObjectType; 

    […] 

} 

然後我們查詢對於所有版本的Identity with:

AuditQuery auditQuery = auditReader.createQuery().forRevisionsOfEntity(
    Identity.class, 
    false, 
    true); 
auditQuery.add(AuditEntity.id().eq(dbid)); 

@SuppressWarnings("unchecked") 
List< Object[]> history = (List< Object[]>) auditQuery.getResultList(); 

如果存儲的身份沒有BusinessObjectType(即,businessObjectType是且爲空),一切都像魅力一樣起作用。

如果身份有businessObjectType != null我們得到了一個「Javassist進行強化失敗」例外:

Javassist Enhancement failed: ch.ethz.id.wai.baseclasses.BusinessObjectType 

的錯誤似乎與Envers試圖實例化一個BusinessObjectType,但我實在看不出有什麼問題可能是(如果我們不使用AuditQuery,Hibernate對兩個對象都沒有問題)。

異常的原因是

java.lang.InstantiationException: ch.ethz.id.wai.baseclasses.BusinessObjectType_$$_javassist_49 

不具有堆棧跟蹤。

任何暗示問題可能是什麼?

回答

14

這發生在以下類中JavassistLazyInitializer基於Javassist的延遲初始化器代理。

沒有看完整的源代碼很難評論,但你可以嘗試以下選項。

  • 關閉延遲加載@ManyToOne關係[這是一個設計決策,因此要小心,如果它不能在整體解決方案適合]
  • 爲你的實體,這是造成問題的一個默認的公共構造[這是比較容易]
  • 關閉反射優化,如果沒有真正hibernate.bytecode.use_reflection_optimizer屬性設置爲false
  • 需要

讓我們知道,如果這有助於

+0

獲取是默認值:SELECT。構造函數不公開。謝謝。我仍然需要理解爲什麼Envers想要實例化比純粹的Hibernate更多的東西。 – Matteo

+0

爲什麼默認的構造函數是'public'?我看到一個潛在的衝突的答案[這裏](http://stackoverflow.com/questions/2935826/why-does-hibernate-require-no-argument-constructor#comment9688725_2971717) –

1

要獲得有關異常的更多信息,請使用IDE的調試工具爲java.lang.InstantiationException設置異常斷點,以在發生基礎異常時停止執行。這應該會顯示完整的堆棧跟蹤,並允許您檢查堆棧上的所有變量。

如果我猜的話,我的第一個懷疑將是自該協會 BusinessObjectType沒有映射偷懶,直接使用Hibernate並不曾嘗試創建該類的代理。相反,Envers似乎是這樣做的。代理是在運行時生成覆蓋所有公共方法的子類。因此,該類或任何公共方法(除了從Object繼承的方法之外)都可以聲明爲final,並且默認的構造方法必須可以訪問該子類。

+0

我有同樣的嫌疑:Envers試圖獲取更多(否則我不會有錯誤)。一個問題是:爲什麼?我怎樣才能避免它?另一方面,BusinessObjectType有一個默認的公共構造函數,沒有最終字段。用普通的Envers,它可以在沒有任何問題的情況下獲取。 – Matteo

+0

...並沒有最後的方法嗎?我對Envers的內部知識還不夠深入。這就是爲什麼我會開始調試以獲取更多信息。 – meriton

+0

其實我沒有注意到,在最後的測試中,我重新建立了構造函數。順便說一句:用公共構造函數finalals方法似乎工作。謝謝! – Matteo