Object
) annotée par
@Entity
.
Cette table doit donc comporter des colonnes pour tous les champs de toutes les classes de la hiérarchie, du moins celles annotées par
@Entity
ou
@MappedSuperClass
. On prendra donc garde aux éventuels problèmes de collisions de nom au niveau des colonnes.
Cette table enregistrera toutes les instances de ces classes : en général plusieurs instances peuvent donc cohabiter. Il n'y a pas d'autre moyen pour discriminer ces instances que de créer une colonne technique, afin d'enregistrer de quelle instance il s'agit, pour chaque ligne.
Il est possible qu'une ligne donnée de cette table n'utilise pas toutes les colonnes définies. Dans notre exemple, toutes les instances de
Personne
auront une valeur nulle dans la colonne de jointure
Bateau
.
Personne
est étendue par une classe
Maire
. La classe
Maire
définit une relation vers une
Commune
.
Exemple 28. Stratégie
SINGLE_TABLE
// // Entité Personne // @Entity @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="TYPE_ENTITE") @DiscriminatorValue("PERSONNE") public class Personne implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column(length=40) private String nom ; @Column(length=40) private String prenom ; // reste de la classe } // // Entité Maire // @Entity @DiscriminatorValue("MAIRE") public class Maire extends Personne { @OneToOne private Commune commune ; // reste de la classe } // // Entité Commune // @Entity public class Commune implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name ; // reste de la classe }
SINGLE_TABLE
. Cette stratégie est indiquée par l'annotation
@Inheritance
. Cette annotation ne peut être posée qu'une seule fois par hiérarchie de classe, sur la classe qui sert de racine à cette hiérarchie.
On redéfinit ici le nom de la colonne technique qui va nous permettre de discriminer les instances de
Personne
et les instances de
Maire
dans cette table, par l'annotation
@DiscriminatorColumn
. De même, cette annotation ne doit être posée qu'une seule fois sur toute la hiérarchie.
Enfin pour nos deux entités
Personne
et
Maire
, on définit la valeur utilisée pour discriminer les instances, par l'annotation
@DiscriminatorValue
.
Examinons le schéma obtenu.
TYPE_ENTITE
dans la table
Personne
, de même que la colonne de jointure
commune_id
, définie par l'entité
Maire
.
VARCHAR
de tailles importantes.
Par ailleurs, il faut garder présent à l'esprit que chaque ligne de cette table aura en général un certain nombre de colonnes nulles. Il faut donc être très prudent lorsque l'on ajoute des contrainte du type
not null
ou
optional=false
sur certaines colonnes.
Dans notre exemple, il n'est pas possible d'ajouter une contrainte pour rendre obligatoire la relation
Maire - Commune
. Cette contrainte se traduirait par une commande SQL
not null
sur la colonne
commune_id
, or cette colonne va porter des valeurs nulles pour toutes les instances de
Personne
qui ne sont pas des
Maire
.