Używamy dziedziczenia pojedynczego stołu dla każdego stołu w naszej aplikacji. Dzięki temu różne instancje tego samego stosu aplikacji działają z tymi samymi obiektami DAO, podczas gdy ich jednostki mogą się nieznacznie różnić potencjalnie zawierające informacje unikalne dla tej instancji. Abstrakcyjna klasa definiuje podstawową strukturę tabeli i rozszerzenie definiuje dodatkowe kolumny, w razie potrzeby przez ten przykład:Czy mogę usunąć kolumnę dyskryminatora w dziedziczeniu pojedynczej tabeli w trybie hibernacji?
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "client")
public abstract class Client extends AbstractPersistable<Long> {
// ...
}
aplikacja A:
@Entity
public class ClientSimple extends Client {
private String name;
// getter, setter
}
aplikacja B:
@Entity
public class ClientAdvanced extends Client {
private String description;
// getter, setter
}
Teraz DAO może pracować z obiektami A i B w obiektach Client
, ale aplikacja B może definiować dodatkowe informacje dla obiektu klienta, które mogą być odczytywane przez metodę zarządzania e do aplikacji B:
aplikacji A:
Client client = new ClientSimple();
clientDao.save(client);
aplikacja B:
Client client = new ClientAdvanced();
clientDao.save(client);
Niestety to oznacza, że jest to kolumna dtype w każdej tabeli (lub inna nazwa, że mogę wybrać) . Czy istnieje sposób, aby się tego pozbyć? Nie potrzebujemy go i korzysta z przestrzeni DB ...
Dzięki!
EDIT
Ważne, aby pamiętać: @MappedSuperclass
nie będzie działać. Używamy QueryDSL jako naszej warstwy abstrakcji HQL. Wymaga to automatycznie generowanych klas typu zapytania dla kwerend typu zapisywania. Zostaną one jednak wygenerowane poprawnie tylko wtedy, gdy klasa abstrakcyjna opatrzona jest adnotacją @Entity
.
To neccessairy ponieważ chcemy kwerendy przeciwko abstrakcyjnej klasy Client
podczas gdy w rzeczywistości zapytań ClientSimple
w zgłoszeniu A i ClientAdvanced
w zgłoszeniu B:
więc w dowolnej aplikacji, to będzie działać:
query.where(QClient.client.name.equals("something");
aw aplikacji B to zadziała:
query.where(QClientSimple.client.description.equals("something else");
EDIT2 - sprowadzają
Wydaje sprowadza się do tego: Czy mogę skonfigurować hibernacji w momencie wdrożyć ją ustawić typ dyskryminatora dla inhertited podmiotu do ustalonej wartości. Więc idąc z moim przykładem Client
zawsze będzie ClientSimple
w jednej aplikacji i ClientAdvanced
w drugiej aplikacji, więc nie muszę przechowywać tych informacji w bazie danych?
Tak jak powiedziałem: każda aplikacja będzie instancją podstawowego stosu aplikacji. Każda aplikacja może definiować dodatkowe kolumny dla ich lokalnej bazy danych, ale WSZYSTKIE obiekty będą tego samego typu dla tej instancji, więc gwarantujemy, że dyskryminator jest zawsze taki sam, co czyni go redundantnym w bazie danych i przypadkiem użycia dla konfiguracji hibernacji.
Którą wersję Querydsl używasz? –
Używamy QueryDSL 2.2.3, ale możemy zaktualizować, jeśli nowsze wersje obsługują zmapowane klasy nadrzędne jako cele kwerend: w ten sposób: '@MappedSuperclass @Table publiczna klasa abstrakcyjna Client ...' + '@ Klasa publiczna @Entity ClientSimple extends Client' == > generuj typy zapytań ... ==> zapytanie: 'QClient.client.name' – Pete
Nie jest obsługiwane bezpośrednio, ale możesz dodać do niego bilet na GitHub. Jest łatwo zaimplementowany. –