Beskrivelse

I den forrige lektion så du, at Hibernate bruger en speciel DTYPE VARCHAR-kolonne til at gemme navnet på en Entity-klasse. Sådan en kolonne kaldes en diskriminator . Det bruges til entydigt at bestemme, hvilken klasse der skal oprettes for en given række i databasen.

Du kan manipulere denne kolonne med @DiscriminatorColumn -annotationen . Eksempel:

@DiscriminatorColumn(name="column_name",   discriminatorType = DiscriminatorType.INTEGER)

Ifølge JPA-specifikationen kan en diskriminator have følgende typer:

  • SNOR
  • CHAR
  • HELTAL

Dog giver Hibernate dig mulighed for at udvide denne liste en smule. Det understøtter disse Java-typer: String, char, int, byte, short, boolean.

Hvis vi bruger INTEGER-typen, hvordan koder man så navnet på Entity-klassen i den? Til dette bruges en anden annotation - @DiscriminatorValue .

Se et eksempel:

@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;
}

I eksemplet ovenfor fortalte vi Hibernate, at diskriminatoren vil bruge kolonnen user_type, som vil gemme numre. Hvis den gemmer værdien 1, betyder det, at rækketypen er Medarbejder, hvis 2 er gemt, så er rækketypen Klient. Enkelt og smukt.

@DiscriminatorValue

Men det er ikke alt. Du kan fortælle Hibernate, hvordan man fortolker typen af ​​en streng, når dens diskriminator er NULL.

Det er faktisk meget enkelt. Du angiver null-værdien for @DiscriminatorValue- annotationen . For eksempel sådan her:

@DiscriminatorValue("null")

Klasseeksempel:

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type",   discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("null")
@Entity
class User {
  int id;
  String name;
  LocalDate birthday;
}

Vi har fortalt Hibernate, at enhver tabelrække, der har NULL i kolonnen brugertype, skal fortolkes som et objekt af typen Bruger.

Men det er ikke alt. Der er en anden interessant værdi for @DiscriminatorValue-annotationen.

Her er dette:

@DiscriminatorValue("not null")

Klasseeksempel:

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="user_type",   discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("not null")
@Entity
class User {
  int id;
  String name;
  LocalDate birthday;
}

Med denne annotation fortalte vi Hibernate, at enhver tabelrække med en ikke-NULL-værdi i kolonnen user_type skulle fortolkes som et objekt af typen User. Men dette er kun tilfældet, hvis der ikke findes en klasse, der har det krævede antal eksplicit angivet.

Sådan vil det fungere for forskellige værdier af diskriminatorerne:

  • 0 - opret et objekt af typen Bruger
  • 1 - opret et objekt af typen Medarbejder
  • 2 - opret et objekt af typen Client
  • 3 - opret et objekt af typen Bruger
  • 4 - opret et objekt af typen Bruger

@DiskriminatorFormel

Men det er ikke alt. For vores diskriminator kan vi angive en heltalsformel, hvormed den vil beregne værdierne for @DiscriminatorValue- annotationen .

Der er en særlig anmærkning til dette, den hedder @DiscriminatorFormula .

Eksempel:

@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;
}

De værdier, der returneres af @DiscriminatorFormula , vil blive sammenlignet af Hibernate med værdierne angivet i @DiscriminatorValue- annoteringerne . Med det kan du skrive ret komplekse scenarier:

@DiscriminatorFormula(
           	"case when address is not null " +
           	"then 'Client' " +
           	"else (" +
           	"   case when occupation is not null " +
           	"   then 'Employee' " +
           	"   else 'Unknown' " +
           	"   end) " +
           	"end "
)