Discriminateur

All lectures for FR purposes
Niveau 1 , Leçon 325
Disponible

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 "
)
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION