Descrizione
Nella lezione precedente, hai visto che Hibernate utilizza una speciale colonna DTYPE VARCHAR per memorizzare il nome di una classe Entity. Tale colonna è chiamata discriminatore . Viene utilizzato per determinare in modo univoco quale classe creare per una determinata riga nel database.
Puoi manipolare questa colonna con l' annotazione @DiscriminatorColumn . Esempio:
@DiscriminatorColumn(name="column_name", discriminatorType = DiscriminatorType.INTEGER)
Secondo la specifica JPA, un discriminatore può avere i seguenti tipi:
- CORDA
- CAR
- NUMERO INTERO
Tuttavia, Hibernate ti consente di espandere un po 'questo elenco. Supporta questi tipi Java: String, char, int, byte, short, boolean.
Se usiamo il tipo INTEGER, allora come codificare il nome della classe Entity in esso? Per questo, viene utilizzata un'altra annotazione: @DiscriminatorValue .
Guarda un esempio:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type", discriminatorType = DiscriminatorType.INTEGER)
@Entity
class User {
int id;
String name;
LocalDate birthday;
}
@Entity
@DiscriminatorValue("1")
class Employee extends User {
String occupation;
int salary;
LocalDate join;
}
@Entity
@DiscriminatorValue("2")
class Client extends User {
String address;
}
Nell'esempio sopra, abbiamo detto a Hibernate che il discriminatore utilizzerà la colonna user_type, che memorizzerà i numeri. Se memorizza il valore 1, significa che il tipo di riga è Dipendente, se 2 è memorizzato, il tipo di riga è Cliente. Semplice e bello.
@DiscriminatorValue
Ma non è tutto. Puoi dire a Hibernate come interpretare il tipo di una stringa quando il suo discriminatore è NULL.
In realtà è molto semplice. Si specifica il valore null per l' annotazione @DiscriminatorValue . Ad esempio, in questo modo:
@DiscriminatorValue("null")
Esempio di classe:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("null")
@Entity
class User {
int id;
String name;
LocalDate birthday;
}
Abbiamo detto a Hibernate che ogni riga di tabella che ha NULL nella colonna user_type dovrebbe essere interpretata come un oggetto di tipo User.
Ma non è tutto. C'è un altro valore interessante per l'annotazione @DiscriminatorValue.
Ecco questo:
@DiscriminatorValue("not null")
Esempio di classe:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("not null")
@Entity
class User {
int id;
String name;
LocalDate birthday;
}
Con questa annotazione, abbiamo detto a Hibernate che qualsiasi riga della tabella con un valore non NULL nella colonna user_type dovrebbe essere interpretata come un oggetto di tipo User. Ma questo è solo per il caso in cui non viene trovata una classe che abbia il numero richiesto specificato in modo esplicito.
Ecco come funzionerà per diversi valori dei discriminatori:
- 0 - crea un oggetto di tipo Utente
- 1 - crea un oggetto di tipo Dipendente
- 2 - crea un oggetto di tipo Client
- 3 - creare un oggetto di tipo Utente
- 4 - creare un oggetto di tipo Utente
@DiscriminatorFormula
Ma non è tutto. Per il nostro discriminatore, possiamo specificare una formula intera in base alla quale calcolerà i valori per l' annotazione @DiscriminatorValue .
C'è un'annotazione speciale per questo, si chiama @DiscriminatorFormula .
Esempio:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorFormula("case when ‘join’ is not null then 1 else 2 end")
@Entity
class User {
int id;
String name;
LocalDate birthday;
}
@Entity
@DiscriminatorValue("1")
class Employee extends User {
String occupation;
int salary;
LocalDate join;
}
@Entity
@DiscriminatorValue("2")
class Client extends User {
String address;
}
I valori restituiti da @DiscriminatorFormula verranno confrontati da Hibernate con i valori specificati nelle annotazioni @DiscriminatorValue . Con esso, puoi scrivere scenari piuttosto complessi:
@DiscriminatorFormula(
"case when address is not null " +
"then 'Client' " +
"else (" +
" case when occupation is not null " +
" then 'Employee' " +
" else 'Unknown' " +
" end) " +
"end "
)
GO TO FULL VERSION