сущности в Hibernate

189
13 января 2022, 01:20

есть SQL две таблицы,пользовататель может пренадлежать только к одной команде.

CREATE TABLE Team
(
id INT auto_increment PRIMARY KEY,
logo VARCHAR(30) NOT NULL unique,
url VARCHAR(30) NOT NULL unique,
name VARCHAR(30) NOT NULL unique
);
CREATE TABLE User
(
id INT auto_increment PRIMARY KEY,
name VARCHAR(30) NOT NULL unique,
email VARCHAR(30) NOT NULL unique,
avatar VARBINARY(50) NOT NULL,
passwort VARCHAR(30) NOT NULL,
team_id INT NOT NULL,
foreign key (team_id) references Team(id) ON UPDATE CASCADE
);

нужно прописать эти сущности в классах,я сделал это так

@Entity(name = "user")
public class User {
    @Id
    @GeneratedValue
    private Integer id;
    @Column(unique = true)
    private String name;
    @Column(unique = true)
    private String email;
    @Column
    private String avatar;
    @Column
    private String passwort;
    @ManyToOne(optional = false,cascade = CascadeType.ALL)
    @JoinColumn (name = "team_id")
    private User user;

@Entity(name = "team")
public class Team {
    @Id
    @GeneratedValue
    private Integer id;
    @Column(unique = true)
    private String logo;
    @Column(unique = true)
    private String url;
    @Column(unique = true)
    private String name;
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<User> userList = new ArrayList<User>();

вопросы - 1 Обязательно ли мне прописывать отношения в обоих сущностях, или достаточно только в user?

2 Всегда ли надо прописывать отношения сущностей в обоих классах?

Answer 1

Список значений hibernate сам сгенерит по team_id в сущности User. Только вы ему должны поле указать, которое он должен использовать для связки из сущности User. И каскадное изменение здесь, думаю, тоже лишнее. И еще таблицу "user" лучше не называть с некоторыми БД могут быть проблемы, можно назвать "users". Поле avatar лучше вынести в отдельную сущность, вряд ли его надо поднимать каждый раз, когда поднимете пользователя. Имя сущности можно не указывать, если оно не отличается от имени класса, Hibernate сам его назначит по умолчанию. Уникальные ключи лучше указывать в аннотации @Table, это позволит указывать ключи состоящие из нескольких полей и задать ключам нормальные имена при генерации БД.

В общем, можно сделать так:

 @Entity
 @Table(name = "users", uniqueConstraints = {
     @UniqueConstraint( name = "uk_users_username", columnNames = "username" ),
     @UniqueConstraint( name = "uk_users_email", columnNames = "email" )
 })
 public class User {
     @Id
     @GeneratedValue
     private Integer id;

     @Column(name = "username", nullable = false, length = 30)
     private String username;
     @Column(name = "email", nullable = false, length = 30)
     private String email;

     @Column(name = "password", nullable = false, length = 30)
     private String passwort;
     @ManyToOne
     //foreignKey=@ForeignKey(name = "fk_user_team") - данное свойство позволяет задать читаемое имя ключа в БД при ее генерации, иначе hibernate создаст ключ с именем которое будет понятно только ему.
     @JoinColumn(name = "team_id", foreignKey=@ForeignKey(name = "fk_user_team"))
     private Team team;
     @OneToOne(mappedBy="user", fetch = FetchType.LAZY )
     private UserDetails details;
 }
 //===========================================================================
 @Entity
 @Table(name = "users_details")
 public class UserDetails{
    @Id
    @GeneratedValue
    private Integer id;
    @OneToOne
    @JoinColumn(name="user_id")
    private User user;
    @Column(name="avatar", length=50)
    private String avatar;
 }
 //===========================================================================

Что касается логотипа команды, вряд ли он должен быть уникальным - обычно делают логотип по умочанию и поднимать его каждый раз, наверное, не целесообразно. Что касается url команды, то в него можно добавить идентификатор команды, и не хранить отдельно его (если этот url не генерится другой системой), да и длина в 30 символов для url маловата, только если там какой-то ключ хранить - в этом случае и поле надо называть team_key... опять же оба поля можно вынести в TeamDetails чтоб их каждый раз не поднимать.

 @Entity
 @Table(name = "teams")
 public class Team {
     @Id
     @GeneratedValue
     private Integer id;
     @Column( name = "team_name", nullable=false, unique = true, length = 30)
     private String name;
     @OneToOne(mappedBy = "team", fetch = FetchType.LAZY)
     private TeamDetails details;
     //В свойстве mappedBy указывется имя поля по которому Team связывается сущность User
     //FetchType.LAZY - указывает на то, чтоб данный список не поднимался по умолчанию при поднятии Team, он будет инициализироваться только после явного запроса - вызова метода getUsers()
     @OneToMany( mappedBy = "team", fetch = FetchType.LAZY  )
     private List<User> users;
}
//=============================================================================
@Entity
 @Table(name = "teams", uniqueConstraints = {
     @UniqueConstraint( name = "uk_team_url", columnNames = "url" ),
 })
 public class TeamDetails {
     @Id
     @GeneratedValue
     private Integer id;
     @Column(name="logo", length = 30, nullable= false)
     private String logo;
     @Column(unique = true, length = 30, nullable= false)
     private String url;
}
READ ALSO
Прошу помощи в понимании интерфейса Future&lt;&gt;

Прошу помощи в понимании интерфейса Future<>

В университете дали задание, написать поискового робота, с помощью ExecutorServise, а доступ к единому индексу должен получаться с помощью Future<>И...

90
Объясните почему нажатие кнопок все равно работает

Объясните почему нажатие кнопок все равно работает

Смотрю видеоурок на тему считывания и записи введеного текста в файл на устройство (https://wwwyoutube

82
Жесты в приложении android

Жесты в приложении android

Как сделать так, чтобы пр свайпе снизу вверх менялась картинка (при каждом новом жесте)? Те есть картинки, которые меняются с помощью seelbar,...

85
Что включено в процесс инициализации класса?

Что включено в процесс инициализации класса?

Конкретно на примере: 1Впервые с момента запуска программы обратились к static-члену (тип int) класса

108