У меня проблема моделирования / понимания частичное , несвязанное наследование с аннотациями JPA.
Вот четыре таблицы:
CREATE TABLE Persons (
id INTEGER NOT NULL,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
PRIMARY KEY (id));
CREATE TABLE Referees (
id INTEGER NOT NULL,
license_nbr VARCHAR(10) DEFAULT NULL NULL,
PRIMARY KEY (id),
CONSTRAINT referees_persons_fk
FOREIGN KEY (id)
REFERENCES Persons (id)
ON DELETE CASCADE
ON UPDATE CASCADE);
CREATE TABLE Coaches (
id INTEGER NOT NULL,
license_nbr VARCHAR(10) DEFAULT NULL NULL,
PRIMARY KEY (id),
CONSTRAINT coaches_persons_fk
FOREIGN KEY (id)
REFERENCES Persons (id)
ON DELETE CASCADE
ON UPDATE CASCADE);
CREATE TABLE Players (
id INTEGER NOT NULL,
registration_nbr VARCHAR(20) DEFAULT NULL NULL,
PRIMARY KEY (id),
CONSTRAINT players_persons_fk
FOREIGN KEY (id)
REFERENCES Persons (id)
ON DELETE CASCADE
ON UPDATE CASCADE);
Мои сокращенные классы сущностей:
@Entity
@Table(name = "Persons")
@Inheritance(strategy = InheritanceType.JOINED)
public class Person implements Serializable
{
@Id
@Column(name = "id")
private Integer id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
...
}
@Entity
@Table(name = "Referees")
public class Referee extends Person implements Serializable
{
@Column(name = "license_nbr")
private String licenseNbr = null;
...
}
@Entity
@Table(name = "Coaches")
public class Coach extends Person implements Serializable
{
@Column(name = "license_nbr")
private String licenseNbr = null;
...
}
@Entity
@Table(name = "Players")
public class Player extends Person implements Serializable
{
@Column(name = "registration_nbr")
private String registrationNbr = null;
...
}
Частичное наследование: сущности-личности могут существовать без какого-либо соответствующего рефери, тренера или игрока.
Непересекающееся наследование: может быть любоеКоличество соответствующих подобъектов, то есть человек может быть одновременно судьей, тренером и игроком, возможно, любой комбинацией из трех.Каждая вложенная таблица может иметь только одну или несколько сущностей, но не несколько.
Обратите внимание, что поскольку наследование является частичным, Person не является абстрактным.Более того, в Person / s нет дискриминатора, потому что наследование не является дизъюнктным.
Возможна ли такая модель в ORM Java?Как бы выглядели аннотации?
У меня проблемы с поиском экземпляров способом, которым я аннотировал классы, используя:
// Michael Jordan: the person who's only a player, too
// EclipseLink 2.1.1 ( 1): ?
// EclipseLink 2.2.0 ( 1): ?
// Hibernate 3.6 (-1): wrong Player instance
Person pe1 = em.find(Person.class, 1);
System.out.println("Loaded person = " + pe1);
// EclipseLink 2.1.1 ( 1): ?
// EclipseLink 2.2.0 ( 1): ?
// Hibernate 3.6 (+1): correct Player instance
Player pl1 = em.find(Player.class, 1);
System.out.println("Loaded player = " + pl1);
// EclipseLink 2.1.1 ( 1): ?
// EclipseLink 2.2.0 ( 1): ?
// Hibernate 3.6 (+1): correct null
Referee re1 = em.find(Referee.class, 1);
System.out.println("Loaded referee = " + re1);
// EclipseLink 2.1.1 ( 1): ?
// EclipseLink 2.2.0 ( 1): ?
// Hibernate 3.6 (+1): correct null
Coach ch1 = em.find(Coach.class, 1);
System.out.println("Loaded coach = " + ch1);
System.out.println();
System.out.println();
// Dirk Nowitzki: the person who's also a player *and* a referee
// EclipseLink 2.1.1 ( 1): ?
// EclipseLink 2.2.0 ( 1): ?
// Hibernate 3.6 (-1): wrong Player instance
Person pe2 = em.find(Person.class, 2);
System.out.println("Loaded person = " + pe2);
// EclipseLink 2.1.1 ( 1): ?
// EclipseLink 2.2.0 ( 1): ?
// Hibernate 3.6 (+1): correct Player instance
Player pl2 = em.find(Player.class, 2);
System.out.println("Loaded player = " + pl2);
// EclipseLink 2.1.1 ( 1): ?
// EclipseLink 2.2.0 ( 1): ?
// Hibernate 3.6 (-1): wrong null
Referee re2 = em.find(Referee.class, 2);
System.out.println("Loaded referee = " + re2);
// EclipseLink 2.1.1 ( 1): ?
// EclipseLink 2.2.0 ( 1): ?
// Hibernate 3.6 (+1): correct null
Coach ch2 = em.find(Coach.class, 2);
System.out.println("Loaded coach = " + ch2);
System.out.println();
System.out.println();
// Blake Griffin: the person who's also a player, referee, *and* coach
// EclipseLink 2.1.1 ( 1): ?
// EclipseLink 2.2.0 ( 1): ?
// Hibernate 3.6 (-1): wrong Player instance
Person pe3 = em.find(Person.class, 3);
System.out.println("Loaded person = " + pe3);
// EclipseLink 2.1.1 ( 1): ?
// EclipseLink 2.2.0 ( 1): ?
// Hibernate 3.6 (+1): correct Player instance
Player pl3 = em.find(Player.class, 3);
System.out.println("Loaded player = " + pl3);
// EclipseLink 2.1.1 ( 1): ?
// EclipseLink 2.2.0 ( 1): ?
// Hibernate 3.6 (-1): wrong null
Referee re3 = em.find(Referee.class, 3);
System.out.println("Loaded referee = " + re3);
// EclipseLink 2.1.1 ( 1): ?
// EclipseLink 2.2.0 ( 1): ?
// Hibernate 3.6 (-1): wrong null
Coach ch3 = em.find(Coach.class, 3);
System.out.println("Loaded coach = " + ch3);
EclipseLink 2.1.1 и 2.2.0. Ночная сборка завершается неудачно на EntityManager.find (...), в то время как Hibernate по крайней мере возвращает некоторые ожидаемые экземпляры.Обратите внимание на слово « Ожидается » здесь.Я понимаю, что должен делать JPA ORM, но я могу ошибаться.
Как видите, Hibernate всегда возвращает экземпляры Player подкласса, но не может найти экземпляры Coach и Referee, если Playerэкземпляр также доступен.
Итак, как JPA лучше всего справляется с этой моделью?