Как вы описали свои сущности, Hibernate будет ожидать следующую структуру базы данных:
oeuvre(idoeuvre, titre, isbn, parution)
magasine(idoeuvre, titre, isbn, parution, type)
livre(idoeuvre, titre, isbn, parution, idauteur)
Это приведет к значительному дублированию, и, вероятно, это не то, что вам нужно.Теперь вы описали два возможных решения, а именно:
Определение одной таблицы с именем oeuvre
, где присутствует каждое поле, например:
oeuvre(idoeuvre, titre, isbn, parution, type, idauteur)
Определение отдельных таблиц для livre
и magasine
, например:
oeuvre(idoeuvre, titre, isbn, parution)
magasine(idmagasine, idoeuvre, idauteur)
livre(idlivre, idoeuvre, idauteur)
Теперь, как вы упоминали, первое решение не позволяетВы должны определить ограничение, в то время как второй делает.По сути, это означает, что вы предоставили свой собственный ответ, если вам нужно ограничение, тогда вам придется различать разные типы, а затем вам придется пойти на второй подход.
Тогда вы можетеОпределите следующие ограничения:
- Каждый
magasine.idoeuvre
и livre.idoeuvre
должны быть уникальными (вы даже можете использовать их в качестве первичного ключа) livre.idauteur
должно быть not null
Однако в этом случае вам не нужно наследование.Наследование в Hibernate обычно выполняется только в том случае, если несколько таблиц имеют одинаковые поля, тогда как в этом случае у вас есть три отдельные таблицы и, следовательно, три отдельных объекта, без наследования:
@Entity
public class Oeuvre {
@Id
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
private String idoeuvre;
@NotNull
private String titre;
@NotNull
private String ISBN;
@ColumnDefault("CURRENT_DATE()")
private LocalDate parution;
}
@Entity
public class Magasine { // No extends
@Id
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
private String idmagasine;
@OneToOne
@JoinColumn(name = "idoeuvre")
private Oeuvre oeuvre;
@Enumerated(EnumType.STRING)
private Type type;
}
@Entity
public class Livre { // No extends
@Id
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
private String idlivre;
@OneToOne
@JoinColumn(name = "idoeuvre")
private Oeuvre oeuvre;
@ManyToOne
@JoinColumn(name = "idauteur")
private Auteur auteur;
}
Единственная причина, по которой вы моглив этом случае используйте наследование, потому что оба Magasine
и Livre
имеют одинаковое отображение Oeuvre
, в этом случае вы можете изменить свой код следующим образом:
@Entity
public class Oeuvre {
@Id
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
private String idoeuvre;
@NotNull
private String titre;
@NotNull
private String ISBN;
@ColumnDefault("CURRENT_DATE()")
private LocalDate parution;
}
@MappedSuperclass // No @Entity
public class SpecificOeuvre {
@OneToOne
@JoinColumn(name = "idoeuvre")
private Oeuvre oeuvre;
}
@Entity
public class Magasine extends SpecificOeuvre {
@Id
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
private String idmagasine;
@Enumerated(EnumType.STRING)
private Type type;
}
@Entity
public class Livre extends SpecificOeuvre {
@Id
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
private String idlivre;
@ManyToOne
@JoinColumn(name = "idauteur")
private Auteur auteur;
}
Оба представляют одну и ту же базу данныхструктура, единственное отличие состоит в том, что у одного из них есть отдельный класс, помеченный @MappedSuperclass
, который содержит всю повторно используемую информацию между Magasine
и Livre
, что в данном случае является только отображением Oeuvre
.
Если вы хотите узнать, связан ли Oeuvre
с Livre
или Magasine
, вы можете использовать двунаправленное отображение, например:
@Entity
public class Oeuvre {
@Id
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
private String idoeuvre;
@NotNull
private String titre;
@NotNull
private String ISBN;
@ColumnDefault("CURRENT_DATE()")
private LocalDate parution;
@OneToOne(mappedBy = "oeuvre")
private Livre livre;
@OneToOne(mappedBy = "oeuvre")
private Magasine magasine;
}
СейчасВы можете увидеть, если дано oeuvre.getMagasine()
или oeuvre.getLivre()
.