Hibernate (JPA) отображение наследования абстрактных суперклассов - PullRequest
29 голосов
/ 24 ноября 2010

Моя модель данных представляет собой юридические лица, такие как бизнес или физическое лицо. Оба являются налогоплательщиками, и у обоих есть TaxID, набор телефонных номеров и набор почтовых адресов.

У меня есть модель Java с двумя конкретными классами, которые расширяют абстрактный класс. Абстрактный класс имеет свойства и коллекции, общие для обоих конкретных классов.

AbstractLegalEntity        ConcreteBusinessEntity    ConcretePersonEntity
-------------------        ----------------------    --------------------
Set<Phone> phones          String name               String first
Set<Address> addresses     BusinessType type         String last
String taxId                                         String middle

Address                    Phone
-------                    -----
AbsractLegalEntity owner   AbstractLegalEntity owner
String street1             String number
String street2           
String city
String state
String zip

Я использую Hibernate JPA Аннотации в базе данных MySQL , с такими классами:

@MappedSuperclass
public abstract class AbstractLegalEntity {
    private Long id;  // Getter annotated with @Id @Generated
    private Set<Phone> phones = new HashSet<Phone>();  // @OneToMany
    private Set<Address> address = new HashSet<Address>();  // @OneToMany
    private String taxId;
}

@Entity
public class ConcretePersonEntity extends AbstractLegalEntity {
    private String first;
    private String last;
    private String middle;
}

@Entity
public class Phone {
    private AbstractLegalEntity owner; // Getter annotated @ManyToOne @JoinColumn
    private Long id;
    private String number;
}

Проблема в том, что Phone и Address объекты должны ссылаться на своего владельца, который является AbstractLegalEntity. Hibernate жалуется:

@OneToOne or @ManyToOne on Phone references an unknown 
entity: AbstractLegalEntity

Похоже, это будет довольно распространенный сценарий наследования Java, поэтому я надеюсь, что Hibernate поддержит его. Я пытался изменить отображение для AbstractLegalEntity на основе вопроса Hibernate на форуме , больше не используя @MappedSuperclass:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

Однако теперь я получаю следующую ошибку. При чтении этого типа отображения наследования создается впечатление, что я должен использовать SEQUENCE, а не IDENTITY, и MySQL не поддерживает SEQUENCE.

Cannot use identity column key generation with <union-subclass> 
mapping for: ConcreteBusinessEntity

Я добиваюсь большего прогресса в том, чтобы все заработало, когда я использую следующее отображение.

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
        name="entitytype",
        discriminatorType=DiscriminatorType.STRING
)

Я думаю, что мне следует идти по этому пути. Меня беспокоит то, что я отображаю это как @Entity, когда я действительно никогда не хочу, чтобы экземпляр AbstractLegalEntity когда-либо существовал. Я хотел бы знать, если это правильный подход. Какой правильный подход я должен использовать в этой ситуации?

Ответы [ 3 ]

42 голосов
/ 25 ноября 2010

Использование:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
AbstractLegalEntity

Тогда в базе данных у вас будет одна таблица для AbstractLegalEntity и таблицы для классов, которые расширяют класс AbstractLegalEntity. У вас не будет экземпляров AbstractLegalEntity, если он абстрактный. Здесь можно использовать полиморфизм.

При использовании:

@MappedSuperclass
AbstractLegalEntity

@Entity
ConcretePersonEntity extends AbstractLegalEntity

Создает в базе данных только одну таблицу ConcretePersonEntity, но со столбцами из обоих классов.

1 голос
/ 24 ноября 2010

Вы должны объявить AbstracLegalEntity как @Entity. Даже с аннотацией @Entity ваш класс остается абстрактным. следовательно, у вас будет только экземпляр конкретных подклассов.

1 голос
/ 24 ноября 2010

Добавить @Entity аннотацию к AbstractLegalEntity. Экземпляр AbstractLegalEntity никогда не будет существовать - hibernate загрузит соответствующие расширяющие экземпляры - ConcreteBusinessEntity или ConcretePersonEntity в соответствии с полем Id.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...