Utilizziamo l'ereditarietà di una tabella per ogni tabella nella nostra applicazione. Ciò consente a diverse istanze dello stesso stack di applicazioni di funzionare con gli stessi DAO mentre le loro entità potrebbero differire leggermente potenzialmente potenzialmente contenenti informazioni univoche per tale istanza. Una classe astratta definisce la struttura della tabella di base e un'estensione definisce colonne aggiuntive, se richiesto, da quella istanza:Posso rimuovere la colonna discriminator in un'ereditarietà della tabella singola di Hibernate?
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "client")
public abstract class Client extends AbstractPersistable<Long> {
// ...
}
applicazione A:
@Entity
public class ClientSimple extends Client {
private String name;
// getter, setter
}
applicazione B:
@Entity
public class ClientAdvanced extends Client {
private String description;
// getter, setter
}
Ora un DAO può funzionare con gli oggetti Client
per le applicazioni A e B, ma l'applicazione B può definire informazioni aggiuntive per il proprio oggetto client che possono essere letti da un metodo di gestione uniqu e per l'applicazione B:
applicazione A:
Client client = new ClientSimple();
clientDao.save(client);
applicazione B:
Client client = new ClientAdvanced();
clientDao.save(client);
Purtroppo questo significa che c'è una colonna DTYPE in ogni tabella (o qualsiasi altro nome che io possa scegliere) . C'è un modo per sbarazzarsi di questo? Non ne abbiamo bisogno e sta utilizzando lo spazio DB ...
Grazie!
EDIT
Importante notare: @MappedSuperclass
non funzionerà. Stiamo utilizzando QueryDSL come il nostro livello di astrazione HQL. Ciò richiede classi di tipo di query generate automaticamente per il tipo di query di salvataggio. Questi tuttavia verranno generati correttamente solo se la classe astratta è annotata con @Entity
.
Questo è neccessairy perché vogliamo interrogare contro la classe astratta Client
mentre in realtà l'interrogazione ClientSimple
in applicazione A e ClientAdvanced
in applicazione B:
Quindi, in qualsiasi applicazione che questo funzionerà:
query.where(QClient.client.name.equals("something");
ed in applicazione B questo lavoro:
query.where(QClientSimple.client.description.equals("something else");
EDIT2 - riducono
E sembra ridursi a questo: Posso configurare ibernazione in fase di deploy per impostare il tipo discriminatore per un'entità inhertited ad un valore fisso. Quindi, con il mio esempio uno Client
sarà sempre ClientSimple
in un'applicazione e ClientAdvanced
nell'altro in modo che non debba memorizzare tali informazioni nel database?
Come ho detto: Ogni applicazione sarà un'istanza dello stack dell'applicazione di base. Ogni applicazione potrebbe definire colonne aggiuntive per il proprio database locale, ma TUTTI gli oggetti saranno dello stesso tipo per quell'istanza, quindi garantiamo che il discriminatore è sempre lo stesso, rendendolo ridondante nel database e un caso d'uso per la configurazione di ibernazione.
Quale versione di Querydsl stai utilizzando? –
Utilizziamo QueryDSL 2.2.3 ma è possibile aggiornare se le versioni più recenti supportano le superclassi mappate come target di query: come segue: '@MappedSuperclass @Table public abstract class Client ...' + '@Entity public class ClientSimple estende Client' == > genera tipi di query ... ==> query: 'QClient.client.name' – Pete
Non è supportato direttamente, ma è possibile aggiungere un ticket per questo su GitHub. È facilmente implementabile. –