При использовании стратегии «таблица на конкретный класс» столбцы таблицы корневого класса дублируются в листовых таблицах. Они будут иметь одинаковые имена. Но что, если применять унаследованную базу данных, а столбцы будут обладать другими именами? JPA задействует аннотацию @AttributeOverride для переопределения отображения одного столбца и @AttributeOverrides, если речь идет о переопределении нескольких.
Чтобы переименовать столбцы ID, TITLE и DESCRIPTION в таблицах BOOK и CD, код сущности Item не потребуется изменять, однако придется задействовать аннотацию @AttributeOverride для сущностей Book (листинг 5.62) и CD (листинг 5.63).
@Entity
@AttributeOverrides({
··@AttributeOverride(name = "id",
·····················column = @Column(name = "book_id")),
··@AttributeOverride(name = "title",
·····················column = @Column(name = "book_title")),
··@AttributeOverride(name = "description",
·····················column = @Column(name = "book_description"))
})
public class Book extends Item {
··private String isbn;
··private String publisher;
··private Integer nbOfPage;
··private Boolean illustrations;
··// Конструкторы, геттеры, сеттеры
}
@Entity
@AttributeOverrides({
··@AttributeOverride(name = "id",
·····················column = @Column(name = "cd_id")),
··@AttributeOverride(name = "title",
·····················column = @Column(name = "cd_title")),
··@AttributeOverride(name = "description",
·····················column = @Column(name = "cd_description"))
})
public class CD extends Item {
··private String musicCompany;
··private Integer numberOfCDs;
··private Float totalDuration;
··private String genre;
··// Конструкторы, геттеры, сеттеры
}
Поскольку требуется переопределить несколько атрибутов, вам необходимо использовать аннотацию @AttributeOverrides, которая принимает массив аннотаций @AttributeOverride. После этого каждая аннотация указывает на атрибут сущности Item и переопределяет отображение столбца с помощью аннотации @Column. Таким образом, name = "title" ссылается на атрибут title сущности Item, а @Column(name = "cd_title") информирует поставщика постоянства о том, что title надлежит отобразить в столбец CD_TITLE. Результат показан на рис. 5.27.
Рис. 5.27. Таблицы BOOK и CD переопределяют столбцы таблицы ITEM
Ранее в разделе «Встраиваемые объекты» этой главы вы видели, что встраиваемый объект может совместно использоваться несколькими сущностями (Address был встроен в Customer и Order). Поскольку встраиваемые объекты — это внутренняя часть владеющей сущности, в таблице каждой сущности также будут иметься дубликаты столбцов, связанных с этими объектами. Кроме того, @AttributeOverrides можно применять, если вам необходимо переопределить встраиваемые столбцы.
Типы классов в иерархии наследования
В примерах, приводившихся ранее для объяснения стратегий отображения, были задействованы только сущности. Item, как и Book и CD, является сущностью. Однако сущностям не всегда приходится наследовать от сущностей. В иерархии классов могут быть смешаны всевозможные разные классы: сущности, а также классы, которые не являются сущностями (или временные классы), абстрактные сущности и отображенные суперклассы. Наследование от этих классов разных типов будет влиять на отображение.