2010-06-17 50 views
3

我有一個子類和一個超類。但是,只有超類的字段需要保留。使用Hibernate作爲超類繼承子類

session.saveOrUpdate((Superclass) subclass); 

如果我這樣做,我會得到以下例外。

org.hibernate.MappingException: Unknown entity: test.Superclass 
    at org.hibernate.impl.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:628) 
    at org.hibernate.impl.SessionImpl.getEntityPersister(SessionImpl.java:1366) 
    at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:203) 
    at org.hibernate.event.def.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:535) 
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:103) 
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93) 
    at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:535) 
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:527) 
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:523) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:342) 
    at $Proxy54.saveOrUpdate(Unknown Source) 

如何將一個子類作爲超類繼承?我不喜歡創建一個超類實例,然後從子類實例傳遞值。因爲如果未來將額外的字段添加到超類中,很容易忘記更新邏輯。

+0

'Superclass'是否被映射?例外情況表明它不是。 – 2010-06-17 09:46:45

+0

Ooops,應該是「org.hibernate.MappingException:未知實體:test.Subclass」。 – franziga 2010-06-17 09:59:49

回答

1

你試圖達到什麼會導致你很多問題。試想一下,如果你再次加載數據會發生什麼。 Hibernate應該使用哪個類?超類?還是其中一個子類?哪一個?

我建議直接映射超類,然後使用delegate pattern來實現擴展功能(基本上將您的超類轉換爲傳遞給「worker」實例的數據對象)。

+0

我只會將數據加載到超類。 如果超類添加了額外的字段,您的建議還需要通知更新委託。 – franziga 2010-06-17 09:59:10

0

我也有興趣找到一種方法來做到這一點。這是一個激勵案例。比方說,我有一個用戶對象來代表我的應用程序中的用戶。 User對象有一些屬性,比如用戶名,密碼,電子郵件地址,名字等,我將把它們存儲在數據庫中。

當我構建讓用戶編輯他們自己的配置文件的屏幕時,我想要一個「更改密碼」的複選框,以便我可以顯示/隱藏密碼框,並且我還希望「確認密碼「字段,所以他們不會錯誤地鍵入它。我不想將這些屬性存儲在數據庫中,它們也不是用戶對象的一部分,所以我不希望這些字段存在於用戶中。但是,許多Web框架使得基於正在編輯的對象構建表單頁面變得更加容易。

我想解決這個問題的方法是創建一個User的子類,我們稱之爲EditableUser,它有一些額外的字段,比如「changePassword」和「confirmPassword」,並在我的表單中使用這個對象。但問題是Hibernate不知道如何保存一個EditableUser對象。 (這也是如何從數據庫中加載的用戶創建EditableUser的問題,但如果您有複製構造函數,則這是可行的)

我最終解決此問題的方式是使用委派:創建一個EditableUser對象,其中包含一個User,以及我不想保存的額外屬性。這合理地工作得很好,除了它意味着我的表單上的所有數據綁定都必須更改爲訪問內部User對象,所以感覺有點混亂。