2012-07-11 8 views
6

Ho modellato le mie classi di dominio in Grails con ereditarietà come mostrato di seguito.Cast di ereditarietà delle classi di domini Graal/Groovy

abstract class Profile{ 
} 

class Team extends Profile{ 
} 

class User extends Profile{ 
} 

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

Più tardi, i controllori quando ricevo tutti i profili dalla classe B in alcune situazioni mi piacerebbe lanciare alcuni dei profili per squadra o per l'utente, ma non posso perché ho ottenere un java. lang.ClassCastException o GroovyCastException, sebbene siano salvati come Team o Utente (con la classe attributo nel database). Ecco i modi che ho provato:

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

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

Si sta lavorando, quando non scrivo qualsiasi tipo basta usare come è normale in un linguaggio dinamico.

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

Ma poi non so mai quale classe sto usando. C'è comunque in groovy o gorm per lanciare la classe genitore al bambino?

+0

Non c'è [discriminatore] (http://grails.org/doc/latest/ref/Database%20Mapping/discriminator.html) per Gorm di scegliere tra ' User' o 'Team'. Come dovrebbe Gorm decidere quale implementazione usare? – krock

+0

Salva nella stessa tabella del database con un attributo di classe che indica quale classe è. – sgleser87

risposta

4

La risposta è No come una vera istanza di GORM/Hibernate è un oggetto con proxy. Quindi non può essere lanciato direttamente su una classe di entità.

Comunque questo potrebbe aiutare:

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

Funziona, ma in realtà non era la mia domanda. La mia domanda era se esiste un modo per lanciare esplicitamente la classe base in sottoclasse. – sgleser87

+3

No, perché il proxy di ibernazione non è necessariamente una 'instanceof' nella sottoclasse nel senso Java della parola. La classe proxy è una sottoclasse generata dinamicamente del tipo _declared_ di 'b.profiles' (ad esempio' Profile'). [Questo articolo] (http://blog.springsource.org/2010/07/28/gorm-gotchas-part-3/) ha i dettagli cruenti, e questo (e gli altri articoli della stessa serie) vale la pena una lettura –

+3

C'è sempre 'GrailsHibernateUtil.unwrapIfProxy', che rimuoverà il wrapper del proxy e ti darà l'oggetto reale (che potrai poi lanciare) ma questo dovrà colpire il database se l'oggetto reale non è già stato caricato. –