Как настроить сопоставления наследования Hibernate с помощью аннотаций Java? В чем преимущества использования наследования в аннотации?
Наследование в аннотациях Hibernate?
Ответ 1
3 возможных типа:
1. Стратегия одиночной таблицы для каждого класса:
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn( name="planetype",
discriminatorType=DiscriminatorType.STRING )
@DiscriminatorValue("Plane")
public class Plane { ... }
@Entity
@DiscriminatorValue("A320")
public class A320 extends Plane { ... }
<hibernate-mapping>
<subclass name="DomesticCat" extends="Cat" discriminator-value="D">
<property name="name" type="string"/>
</subclass>
- Плюсы: прост. Не требуется никаких JOINs
- Минусы: нельзя использовать нули. Число столбцов увеличивается с глубиной графа объекта.
2. Присоединительная стратегия подкласса:
Таблицы базы данных
CREATE TABLE SUPER_TABLE(
id_col number primary key,
sup_Name varchar2(20));
CREATE TABLE SUB_TABLE(
SUP_ID primary key,
sub_name varchar2(20),
constraint SUB_TABLE_fk foreign key (sup_Id) references super_table(id_col));
@Entity
@Table(name= "SUPER_TABLE")
@Inheritance(strategy= InheritanceType.JOINED)
public class TestSuperClass {
@Id
@GeneratedValue(
strategy=GenerationType.SEQUENCE,
generator="SEQ_GEN")
@SequenceGenerator(
name="SEQ_GEN",
sequenceName="hibernate_sequence"
)
@Column(name ="id_col")
private long idcol;
@Column(name ="sup_name")
private String supName;
@Entity
@Table(name="SUB_TABLE")
@PrimaryKeyJoinColumn(name="SUP_ID")
<class name="Payment" table="PAYMENT">
<id name="id" type="long" column="PAYMENT_ID">
<generator class="native"/>
</id>
<property name="amount" column="AMOUNT"/>
...
<joined-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
<key column="PAYMENT_ID"/>
<property name="creditCardType" column="CCTYPE"/>
...
</joined-subclass>
<joined-subclass name="CashPayment" table="CASH_PAYMENT">
<key column="PAYMENT_ID"/>
...
</joined-subclass>
public class TestSubClass extends TestSuperClass{
private String sub_name;
}
Модуль тестирования
TestSubClass sub = new TestSubClass("sub1");
sub.setSupName("supersuper"); session1.save(sub);
SQL Generated
Hibernate: insert into SUPER_TABLE (sup_name, id_col) values (?, ?)
Hibernate: insert into SUB_TABLE (sub_name, SUP_ID) values (?, ?)
- Плюсы: Нормализованные структуры данных.
- Минусы: ПРИСОЕДИНИТЬСЯ всегда.
3. Таблица для конкретной стратегии класса:
create table CREDIT_CARD( payment_id number primary key, amount
number, creditCardType varchar2(2) );
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class Payment {
@Id
@GeneratedValue(
strategy=GenerationType.SEQUENCE,
generator="SEQ_GEN")
@SequenceGenerator(
name="SEQ_GEN",
sequenceName="hibernate_sequence"
)
@Column(name = "payment_id")
private long id;
private double amount;
@Entity
@Table(name="CREDIT_CARD")
public class CreditCardPayment extends Payment {
private String creditCardType;
<class name="Payment">
<id name="id" type="long" column="PAYMENT_ID">
<generator class="sequence"/>
</id>
<property name="amount" column="AMOUNT"/>
...
<union-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
<property name="creditCardType" column="CCTYPE"/>
...
</union-subclass>
Модуль тестирования
CreditCardPayment credit = new CreditCardPayment("C",1.0);
session1.save(credit);
SQL Generated
Hibernate: insert into CREDIT_CARD (amount, creditCardType, payment_id) values (?, ?, ?)
Там также @MappedSuperClass, который мы использовали в нашем приложении.
Ответ 2
Это очень общий вопрос, но я бы посоветовал посмотреть на следующие ресурсы:
- Документация о том, как наследование объявляется с помощью аннотаций Hibernate.
- Этот файл PDF (глава 2 книги о спящем режиме). Направляющие работают с аннотациями Hibernate.
Но самый простой ответ на ваш вопрос заключается в том, что вы должны использовать аннотацию @Inheritance
, например:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Flight implements Serializable {
...
}
Ответ 3
Я бы предложил использовать аннотацию @Inheritance над @MappedSuperclass. У нас были проблемы в прошлом, когда @MappedSuperclass был достаточно гибким для наших текущих потребностей в обслуживании.