Разные двунаправленные родительские @ManyToOne для 2 сущностей, расширяющие некоторые базовые сущности, но хранящие данные базовых сущностей в одной таблице - PullRequest
0 голосов
/ 27 ноября 2018

Это название ближе всего к тому, что я пытаюсь сделать.:)

Давайте начнем с того, как это должно выглядеть в базе данных (таблицы со столбцами):

Email
  - id : PK
  - email : String
CompanyEmail
  - email_id : FK
  - company_id : FK
PersonEmail
  - email_id : FK
  - person_id : FK
Company
  - id : PK
Person
  - id : PK

Теперь давайте посмотрим на модель:

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

    @OneToMany
    private List<CompanyEmail> emails = new ArrayList<>();
}

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

    @OneToMany
    private List<PersonEmail> emails = new ArrayList<>();
}

// Should this be @Entity? Maybe @MappedSuperclass? What strategy to use to be able to extend it?
public class Email // This is base email class/entity
{
    @Id
    @GeneratedValue
    private Long id;

    @javax.validation.constraints.Email
    private String email;
}

@Entity
public class PersonEmail // This needs to somehow extend Email, so all Email data is also accessible here.
{
    @ManyToOne
    private Person person;
}

@Entity
public class ComanyEmail // This needs to somehow extend Email, so all Email data is also accessible here.
{
    @ManyToOne
    private Company company;
}

Теперь мой вопросэто - возможно ли в Hibernate (последней) достичь такой структуры?

Ключевые моменты при разработке выше (что меня подвигло):

  • Храните ВСЕ письма в одной таблице, для здравомыслияпроверяет (уникальность).
  • имеет наименьшую площадь базы данных - выше приведена только одна таблица для Email, а затем 2 таблицы объединения с 2 FK.
  • По-прежнему можно сохранять дизайн модели. Hibernate-дружественный (в основном не использует никаких специальных запросов, только аннотации JPA).Это означает, что и Компания, и Персона могут легко LAZY загружать свои конкретные электронные письма (подклассы), а также эти электронные письма в подклассе могут соответствовать им (PersonEmail до Person и CompanyEmail до Company), что делает модель двунаправленной.

Примечание: я также подумал о создании чего-то вроде Contactable базового класса для Comapny и Person, в котором был бы список Email, но это не соответствует моим потребностям (никласс на таблицу, ни один и тот же дизайн таблицы).

Мой вопрос - возможно ли ?Даже если я не получу ответ с примером, основанным на занятиях, которые я давал, сам факт даст мне надежду, и я найду его.

Редактировать 1

Должен ли я использовать дискриминатор в таблице электронной почты и затем хранить там ФК?

Email
  - id : PK
  - email : String
  - companyOrPerson : FK
  - discriminator : Decides what FK points at
Company
  - id : PK
Person
  - id : PK

Здесь я хватаю соломинку - понятия не имею, возможна ли такая вещь, может ли дискриминатор решить вопрос о родительской таблице(companyOrPerson)?Работает ли двунаправленная работа здесь (как я уже говорил, может быть, мне стоит создать базовый класс Contactable)?

Я открыт для предложений о том, как это сделать хорошо.

1 Ответ

0 голосов
/ 27 ноября 2018

Пользу композиции над наследством.Это имеет тенденцию упрощать вещи.

Если у вас были основные сущности

  • Персона
  • Компания
  • Электронная почта

Затем несколько композитов

  • PersonEmail (содержит человека и электронное письмо)
  • CompanyEmail (содержит компанию и электронное письмо)

Разве это не подходит для вас?

например

@Entity
public class Person {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;

    @OneToMany
    @JoinColumn(name="person_id")
    private List<PersonEmail> emails = new ArrayList<>();

}

@Entity
public class Company {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;

    @OneToMany()
    @JoinColumn(name="company_id")
    private List<CompanyEmail> emails = new ArrayList<>();
}

@Entity
public class Email {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;

    @javax.validation.constraints.Email
    private String email;

}

@Entity
public class PersonEmail {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;

    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="person_id",  referencedColumnName="id")
    private Person person;

    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="email_id",  referencedColumnName="id")
    private Email email;

}

@Entity
public class CompanyEmail
{
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;

    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="company_id",  referencedColumnName="id")
    private Company company;

    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="email_id",  referencedColumnName="id")
    private Email email;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...