Как сделать связи @OneToOne и @ManyToOne в Spring-проекте и таблицах БД?
Spring изучаю совсем недавно, поэтому заранее извиняйте. Пишу проект, где имеется три сущности - это Админ, Повар и Пользователь. Насколько я понял, лучше в БД не создавать для каждого класса отдельную таблицу, а сделать одну таблицу User со всеми основными полями, а уже потом к ней через связи соединять остальные(я не знаю как это правильно называется). Вопрос следующий: как реализовать все это в java-коде и как это сделать в таблицах БД. Правильно ли я понимаю, что нам необходима связь @OneToOne.
User:
package com.tinychiefdelights.model;
import lombok.Data;
import javax.persistence.*;
@Data
@Entity // позволяет включать класс и его jpa аннотации в производный класс,
// не делая базовый класс сущностью.
@Table(name = "pg_user", schema = "public")
public class User {
public User(){ // Пустой конструктор для Hibernate
}
public User(String name, String lastName, String role,
String login, String password){ // Базовый конструктор для дочерних классов
this.name = name;
this.lastName = lastName;
this.role = role;
this.login = login;
this.password = password;
}
// Поля
private @Id @GeneratedValue Long id;
@Column(name = "login")
private String login;
@Column(name = "password")
private String password;
@Column(name = "role")
private String role;
@Column(name = "name")
private String name;
@Column(name = "last_name")
private String lastName;
}
Admin:
package com.tinychiefdelights.model;
import lombok.Data;
import javax.persistence.*;
@Data
@Entity
@Table(name = "pg_user", schema = "public")
public class Admin extends User {
public Admin(){ // Пустой конструктор для Hibernate
}
public Admin(String name, String lastName, String role, String login, String password) { // Вызываем родительский конструктор
super(name, lastName, role, login, password);
}
// Поля
private @Id @GeneratedValue Long id;
// @OneToOne(mappedBy = "pg_user")
// private User user;
// Поля name, lastName, role, login, password наследуются от класса User;
}
Cook:
package com.tinychiefdelights.model;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.tinychiefdelights.service.CookService;
import com.tinychiefdelights.service.CookType;
import lombok.Data;
import javax.persistence.*;
import java.util.List;
@Data
@Entity
@Table(name = "cook", schema = "public")
public class Cook extends User {
public Cook(){ // Пустой конструктор для Hibernate
}
public Cook(String name, String lastName, String role, String login, String password,
CookType cookType, float rating, boolean cookStatus,
List<Review> reviewList, String aboutCook){ // Вызываем родительский конструктор вместе со своими полями
super(name, lastName, role, login, password);
this.cookType = cookType;
this.rating = rating;
this.cookStatus = cookStatus;
this.reviewList = reviewList;
this.aboutCook = aboutCook;
}
// Поля
private @Id @GeneratedValue Long id;
private CookType cookType;
private float rating;
private boolean cookStatus;
// Поля name, lastName, login, password наследуются от класса User;
}
Ответы (1 шт):
Чтобы обеспечить связь @OneToOne мы в классе Cook:
@OneToOne
@JoinColumn(name = "user_id", referencedColumnName = "id") // Join without Cook in User class
private User user;
При этом в таблице Cook создаем ключ со ссылкой на id таблицы User.
user_id int references user(id) on update cascade on delete cascade;
Чтобы обеспечить связь @OneToMany мы в классе Cook:
@OneToMany(mappedBy = "cook", cascade = CascadeType.ALL)
@JsonManagedReference // Таким образом я предотвратил рекурсию
private List<Review> reviewList;
А в классе Review пишем:
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JsonBackReference// Таким образом я предотвратил рекурсию
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
private Cook cook;
В таблице review создаем ключ с привязкой к id cook:
cook_id int references cook(id) on update cascade on delete cascade;