2012-03-12 11 views
42

Utilizzo Play Framework 1.2.4 con PostgreSQL e JPA. Mi piacerebbe avere una gerarchia di modelli e vedere che ci sono alcune alternative per farlo.JPA: Implementazione della gerarchia del modello - @MappedSuperclass vs. @Interitance

Ho una classe base (che è astratta) e due classi concrete che estendono questa classe base. Non voglio mantenere questa classe base mentre voglio avere lezioni concrete. Nella classe base, ho un altro modello di classi come proprietà, in altre parole, ho relazioni @ManyToOne nella mia classe base.

La mia domanda è qual è il modo migliore di implementarlo? Utilizzare @MappedSuperclass o @Inheritance con la strategia TABLE_PER_CLASS? Sono un po 'confuso come sembrano virtualmente equivalente.

Ho anche qualche dubbio sull'interrogazione e sui problemi di prestazioni che potrei dover affrontare in futuro.

+1

Ho cambiato '@ Inheritence' in' @ Inheritance', come presumo fosse un errore di battitura. –

risposta

96

MappedSuperClass deve essere utilizzato per ereditare proprietà, associazioni e metodi.

L'ereditarietà di entità deve essere utilizzata quando si dispone di un'entità e di più sottounità.

Si può dire se è necessario l'uno o l'altro rispondendo a queste domande: c'è qualche altra entità nel modello che potrebbe avere un'associazione con la classe base?

Se sì, la classe base è in effetti un'entità e si deve utilizzare l'ereditarietà dell'entità. Se no, la classe base è in effetti una classe che contiene attributi e metodi comuni a diverse entità non correlate e si dovrebbe utilizzare una superclasse mappata.

Ad esempio:

  • Si possono avere diversi tipi di messaggi: SMS, messaggi di posta elettronica o messaggi telefonici. E una persona ha una lista di messaggi. Puoi anche avere un promemoria collegato a un messaggio, indipendentemente dal tipo di messaggio. In questo caso, Message è chiaramente un'entità e deve essere utilizzata l'ereditarietà dell'entità.
  • Tutti gli oggetti di dominio possono avere una data di creazione, una data di modifica e un ID e pertanto è possibile ereditarli da una classe di base AbstractDomainObject. Ma nessuna entità avrà mai un'associazione con un oggetto AbstractDomainObject. Sarà sempre un'associazione con un'entità più specifica: cliente, azienda, qualunque cosa. In questo caso, ha senso usare MappedSuperClass.
+0

Mille grazie per la tua risposta. Ora sono chiaro che se ho bisogno di persistere o utilizzare la classe base come entità, dovrei usare l'ereditarietà dell'entità. Mi chiedo se c'è un problema con le prestazioni o la restrizione sulle query, specialmente usando le relazioni di oggetti ereditate? – huzeyfe

+0

Tutto dipende dal tipo di eredità che si sceglie e dalla strategia di ereditarietà. –

+0

Nel mio caso (dato che non voglio mantenere la classe base) MappedSuperClass sembra più adatto. Quindi in termini di prestazioni e restrizioni devo essere consapevole di alcuni problemi? – huzeyfe

2

Come ho spiegato nel this article, @MappedSupperclass è diverso dal @Inheritance annotazione.

@MappedSuperclass indica al provider JPA di includere le proprietà persistenti della classe base come se fossero dichiarate dalla classe figlia che estende la superclasse annotata con @MappedSuperclass.

Tuttavia, l'ereditarietà è visibile solo nel mondo OOP, dal momento che, dal punto di vista del database, non c'è alcuna indicazione della classe base. Solo l'entità di classe figlio avrà una tabella associata associata.

L'annotazione @Inheritance ha lo scopo di materializzare il modello di ereditarietà OOP nella struttura della tabella del database. Inoltre, è possibile eseguire una query su una classe base annotata con @Inheritance ma non è possibile farlo per una classe base annotata con @MappedSuperclass.

Ora, il motivo per cui si desidera utilizzare lo @Inheritance JPA annotation is to implement behavior-driven patterns like the Strategy Pattern.

D'altra parte, @MappedSuperclass è solo un modo per riutilizzare sia le proprietà di base, le associazioni e persino l'entità @Id utilizzando una classe di base comune. Tuttavia, è possibile raggiungere quasi lo stesso obiettivo utilizzando un tipo @Embeddable. L'unica differenza principale è che non è possibile riutilizzare una definizione @Id con @Embeddable, ma è possibile farlo con @MappedSuperclass.

Problemi correlati