JPA: Полиморфная ассоциация и объединенная таблица - PullRequest
0 голосов
/ 18 сентября 2018

Я довольно новичок в Hibernate и JPA.У меня есть класс Identity, который имеет отношение один к одному с EntityInformation, который подклассами является либо PersonalInformation, либо CompanyInformation.

Я пытаюсь использовать стратегию Joined table, чтобы оставаться СУХОЙ, чтобы основаТаблица EntityInformation в базе данных имеет общие поля, в то время как таблицы PersonalInformation и CompanyInformation имеют только специфичные для класса поля

Когда я создаю идентификатор с типом «Компания», я хочу создать CompanyInformation для этого идентификатора.У меня проблема в том, что при создании Identity сохраняется EntityInformation, а не Personal / CompanyInformation.

Возможно ли это?Я чувствую, что упускаю что-то или мне нужно моделировать вещи по-другому.Любая помощь будет принята с благодарностью!


Вот мой класс Identity:

@Entity
@Table(name = "identities")

public class Identity {

  @NotNull
  @Enumerated(EnumType.STRING)
  // type is either Personal or Company
  private IdentityType type;

  @NotNull
  @OneToOne(
    mappedBy = "identity", cascade = CascadeType.ALL, orphanRemoval = true, optional = false)

  private EntityInformation entityInformation;
  ...
}

Класс EntityInformation:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "entity_informations")

public class EntityInformation {

  @NotNull private Boolean hasTaxPayerId;

  @OneToOne(optional = false)
  @JoinColumn(name = "identity_id", nullable = false)
  private Identity identity;
  ...    
}

Класс PersonalInformation:

public class PersonalInformation extends EntityInformation{

  @NotBlank private String firstName;

  @NotBlank private String lastName;

  private String middleName;
  ...
}

CompanyInformation класс:

public class CompanyInformation extends EntityInformation{

  @NotBlank private String name;
  ...
}

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

выглядит хорошо для дизайна, за исключением того, что я не вижу ids.Вы должны удалить optional = false на Identity.Это свойство доступно только для извлечения, так как EntityInformation является владельцем отношения, и в схему Identity ничего не помещается.Это вызывает проблему с курицей и яйцом, потому что вы не можете создавать обе новые сущности и сохранять их в одной и той же транзакции. Ни одна из них не может быть нулевой, но одну нужно сохранить перед другой.Я проверил это, и оно сохранилось для меня EntityInformation и CorporateInformation.

@Entity
public class Identity {
    @Id @GeneratedValue
    private Long id;

    @OneToOne(mappedBy = "identity", cascade = CascadeType.ALL, orphanRemoval = true)
    private InformationBase information;

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public abstract class InformationBase {
    @Id @GeneratedValue
    private Long id;

    @OneToOne(optional = false)
    @JoinColumn(name = "identity_id", nullable = false)
    private Identity identity;

@Entity
public class CorporateInformation extends InformationBase {

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

tx.begin();

Identity identity = new Identity();
CorporateInformation corporateInformation = new CorporateInformation();
corporateInformation.setIdentity(identity);
em.persist(identity);
em.persist(corporateInformation);

tx.commit();

показывает в журналах

Hibernate: create table CorporateInformation (id bigint not null, primary key (id))
Hibernate: create table Identity (id bigint not null, primary key (id))
Hibernate: create table InformationBase (id bigint not null, identity_id bigint not null, primary key (id))
Hibernate: create table PersonalInformation (id bigint not null, primary key (id))
Hibernate: alter table InformationBase drop constraint if exists UK_s2ny1w2e3fpckgv97n4bhe49h
Hibernate: alter table InformationBase add constraint UK_s2ny1w2e3fpckgv97n4bhe49h unique (identity_id)
Hibernate: create sequence hibernate_sequence start with 1 increment by 1
Hibernate: alter table CorporateInformation add constraint FKq69d75va3x785scp4iki8kprs foreign key (id) references InformationBase
Hibernate: alter table InformationBase add constraint FK9g3vjjvp7ohn3dfirh6u8mwrx foreign key (identity_id) references Identity
Hibernate: alter table PersonalInformation add constraint FK6muqauf869dw0x9jb7jlhcpwo foreign key (id) references InformationBase
Hibernate: call next value for hibernate_sequence
Hibernate: call next value for hibernate_sequence
Hibernate: insert into Identity (id) values (?)
Hibernate: insert into InformationBase (identity_id, id) values (?, ?)
Hibernate: insert into CorporateInformation (id) values (?)
0 голосов
/ 18 сентября 2018

Ваша идентификационная таблица немного сбивает с толку.Он имеет отношение «один к одному» с сущностью и определяет тип сущности.На данном этапе разработки лучше денормализовать вашу схему и сохранить типы в сущностях.

Преимущества: лучшая производительность (без дополнительного объединения), ясность и меньшие накладные расходы при каскадных проблемах.

Вы можете добавить новое поле в EntityInformation с типом и определить его в дочерних объектах(если вам это нужно).

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