Description
Dans la leçon précédente, vous avez vu qu'Hibernate utilise une colonne spéciale DTYPE VARCHAR pour stocker le nom d'une classe Entity. Une telle colonne s'appelle un discriminateur . Il est utilisé pour déterminer sans ambiguïté quelle classe créer pour une ligne donnée dans la base de données.
Vous pouvez manipuler cette colonne avec l' annotation @DiscriminatorColumn . Exemple:
@DiscriminatorColumn(name="column_name", discriminatorType = DiscriminatorType.INTEGER)
Selon la spécification JPA, un discriminateur peut avoir les types suivants :
- CHAÎNE
- CARBONISER
- ENTIER
Cependant, Hibernate vous permet d'étendre un peu cette liste. Il prend en charge ces types Java : String, char, int, byte, short, boolean.
Si nous utilisons le type INTEGER, alors comment y coder le nom de la classe Entity ? Pour cela, une autre annotation est utilisée - @DiscriminatorValue .
Regardez un exemple :
@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;
}
Dans l'exemple ci-dessus, nous avons indiqué à Hibernate que le discriminateur utilisera la colonne user_type, qui stockera les nombres. S'il stocke la valeur 1, cela signifie que le type de ligne est Employé, si 2 est stocké, alors le type de ligne est Client. Simple et beau.
@DiscriminatorValue
Mais ce n'est pas tout. Vous pouvez indiquer à Hibernate comment interpréter le type d'une chaîne lorsque son discriminateur est NULL.
C'est en fait très simple. Vous spécifiez la valeur nulle pour l' annotation @DiscriminatorValue . Par exemple, comme ceci :
@DiscriminatorValue("null")
Exemple de classe :
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("null")
@Entity
class User {
int id;
String name;
LocalDate birthday;
}
Nous avons dit à Hibernate que toute ligne de table qui a NULL dans la colonne user_type doit être interprétée comme un objet de type User.
Mais ce n'est pas tout. Il existe une autre valeur intéressante pour l'annotation @DiscriminatorValue.
Voici ceci :
@DiscriminatorValue("not null")
Exemple de 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;
}
Avec cette annotation, nous avons indiqué à Hibernate que toute ligne de table avec une valeur non NULL dans la colonne user_type doit être interprétée comme un objet de type User. Mais ce n'est que pour le cas où une classe n'est pas trouvée qui a le nombre requis explicitement spécifié.
Voici comment cela fonctionnera pour différentes valeurs des discriminateurs :
- 0 - crée un objet de type Utilisateur
- 1 - créer un objet de type Employé
- 2 - créer un objet de type Client
- 3 - créer un objet de type Utilisateur
- 4 - créer un objet de type Utilisateur
@DiscriminatorFormula
Mais ce n'est pas tout. Pour notre discriminateur, nous pouvons spécifier une formule entière par laquelle il calculera les valeurs de l' annotation @DiscriminatorValue .
Il existe une annotation spéciale pour cela, elle s'appelle @DiscriminatorFormula .
Exemple:
@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;
}
Les valeurs renvoyées par @DiscriminatorFormula seront comparées par Hibernate avec les valeurs spécifiées dans les annotations @DiscriminatorValue . Avec lui, vous pouvez écrire des scénarios assez complexes :
@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