Как Hibernate различает тип объекта с помощью InheritanceType.JOINED - PullRequest
0 голосов
/ 19 марта 2019

У меня в приложении Spring разные типы пользователей. Я реализовал какое-то наследование. Все типы пользователей расширяются от класса User. Я думаю, что здесь должно быть достаточно двух таблиц:

  1. таблица «пользователи» - содержит столбцы для всех атрибутов общего объекта
  2. таблица "users_corporate" - содержит столбцы для атрибутов класса CorporateCustomer: companyName и VatNumber

«пользователи» будут иметь: идентификатор, имя пользователя, пароль, имя, фамилию, фамилию, адрес электронной почты, мобильный телефон, город, улицу, почтовый индекс

"users_corporate" будет иметь: company_name, vat_number

Class RetailCustomer и Provider не имеют полей с аннотацией @Column, поэтому для них нет необходимости иметь таблицу, мне нужно только объявить поля с сопоставлениями OneToMany. Теперь мне интересно, как hibernate будет отличать Provider и RetailCustomer друг от друга, если у меня нет аннотации @Table в их классе. Когда я буду использовать репозиторий Spring Data и, например, вызывать providerRepository.findAll (), как теперь будет, какие строки из таблицы «users» являются провайдерами, а какие - retailCustomer? Это будет работать? Я что-то упустил?

BaseEntity:

@MappedSuperclass
public class BaseEntity{

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

Пользователь:

@Entity
@Table(name="users")
@Inheritance(strategy = InheritanceType.JOINED)
public class User extends BaseEntity{

    @Column(name = "username")
    private String userName;

    @Column(name = "password")
    private String password;

    @Column(name = "email")
    private String email;

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "users_roles", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Collection<Role> roles;

}

CorporateCustomer:

@Entity
@Table(name="users_corporate")
public class CorporateCustomer extends User{

    @Column(name = "company_name")
    private String companyName;

    @Column(name = "vat_number")
    private String vatNumber;

    @OneToMany(mappedBy = "customer")
    private List<Appointment> appointments;
}

RetailCustomer:

@Entity
//@Table  <---- i think it is not needed here?
public class RetailCustomer extends User {

    @OneToMany(mappedBy = "customer")
    private List<Appointment> appointments;
}

Поставщик:

@Entity
//@Table  <---- i think it is not needed here?
public class Provider extends User{

    @OneToMany(mappedBy = "provider")
    private List<Appointment> appointments;

    @ManyToMany
    @JoinTable(name="works_providers", joinColumns=@JoinColumn(name="id_user"), inverseJoinColumns=@JoinColumn(name="id_work"))
    private List<Work> works;

    @OneToOne(mappedBy="provider", cascade = {CascadeType.ALL})
    private WorkingPlan workingPlan;
}

1 Ответ

0 голосов
/ 19 марта 2019

Как hibernate будет отличать Provider и RetailCustomer друг от друга, если у меня нет аннотации @Table в их классе?

Если вы не укажете имя таблицы с помощью @Table,Таблица будет иметь то же имя, что и имя объекта.

Когда я вызываю providerRepository.findAll (), как теперь будет, какие строки из таблицы "users" являются провайдерами, а какие - retailCustomer?

При выборе из ProviderRepository hibernate генерирует inner join.Будут возвращены только объекты провайдера.Hibernate генерирует собственный SQL:

select ... from Provider p
inner join User u on p.id=u.id

Для выбора всех пользователей с UserRepository hibernate сгенерирует left join.Результат будет содержать все возможные типы пользователей.Hibernate генерирует собственный SQL:

select ..., 
case 
when r.id is not null then 1 
when p.id is not null then 2 
when u.id is not null then 0 
end as clazz_0_ 
from User u
left outer join Provider p on p.id=u.id 
left outer join RetailCustomer r on r.id=u.id

clazz_0_ вспомогательный столбец определяет, какой класс сущности будет создан.

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