2012-07-11 96 views
6

我已經使用繼承在Grails中建模了我的域類,如下所示。Grails/Groovy域類的繼承性演變

abstract class Profile{ 
} 

class Team extends Profile{ 
} 

class User extends Profile{ 
} 

class B{ 
    static hasMany = [profiles: Profile] 
} 

時,我得到的所有曲線從B類在某些情況下,我想投一些配置文件到團隊或用戶控制器之後,但我不能,因爲我得到一個Java。 lang.ClassCastException或GroovyCastException,儘管它們保存爲Team或User(在數據庫中具有屬性類)。以下是我已經試過的方法:

def team1 = b.profiles.toList()[0] as Team 

def team1 = (Team)b.profiles.toList()[0] 

它工作時,我不寫任何類型的只是使用它,因爲它是一個動態語言正常。

def team1 = b.profiles.toList()[0] 

但後來我永遠不知道我正在使用哪個類。無論如何,groovy或gorm會把父母班教給孩子嗎?

+0

沒有[鑑別](http://grails.org/doc/latest/ref/Database%20Mapping/discriminator.html)爲格姆之間'選擇用戶或團隊。 gorm應該如何決定使用哪個實現? – krock 2012-07-11 10:07:58

+0

它保存到數據庫中的同一個表中,並具有指示哪個類的類屬性。 – sgleser87 2012-07-11 10:42:52

回答

4

答案是作爲一個真正的GORM/Hibernate實例是一個代理對象。所以它不能直接轉換爲實體類。

無論如何,這可能幫助:

def team1 = b.profiles.toList()[0] 
if(team1.instanceOf(Team)) { 
    // I am an instance of Team 
    // do something here. 
} 
+0

它正在工作,但實際上這不是我的問題。我的問題是如果有一種方法可以將基類明確地轉換爲子類。 – sgleser87 2012-07-11 15:17:21

+3

不,因爲hibernate代理不一定是'instanceof'這個詞在Java中的子類。代理類是'b.profiles'的_declared_類型(即'Profile')的一個動態生成的子類。 [這篇文章](http://blog.springsource.org/2010/07/28/gorm-gotchas-part-3/)有血淋淋的細節,它(和同系列中的其他文章)非常值得閱讀。 – 2012-07-11 22:47:31

+3

總有'GrailsHibernateUtil.unwrapIfProxy',它將移除代理包裝併爲您提供真實對象(您可以隨後投射),但如果實際對象尚未加載,則必須點擊數據庫。 – 2012-07-11 22:55:05