Как реализовать взаимосвязь «Один ко многим» между непервичными ключами?

#java #hibernate #spring-data-jpa

Вопрос:

У меня есть три таблицы/объекта: отели, типы номеров и номера. В каждом отеле есть несколько типов номеров (одноместные, двухместные и т.д.), И с каждым типом номеров связано несколько номеров.

 CREATE TABLE hotels(
   id BIGSERIAL PRIMARY KEY,
   hotel_id UUID NOT NULL
);

CREATE TABLE room_types(
   id BIGSERIAL PRIMARY KEY,
   hotel_id UUID NOT NULL,
   room_type_id UUID NOT NULL,
   FOREIGN KEY(hotel_id) REFERENCES hotels(hotel_id)
);

CREATE TABLE rooms(
   id BIGSERIAL PRIMARY KEY,
   room_type_id UUID NOT NULL,
   room_id UUID NOT NULL,
   FOREIGN KEY(room_type_id) REFERENCES room_types(room_type_id)
);
 

Более того, мое задание состоит в том, чтобы создать эти таблицы таким образом, чтобы они отражали историю изменений каждой сущности, например

 hotels
---------------------------------
| id | hotel_id | hotel_name
---------------------------------
| 1  | 501      | 'Grand Royale' 
| 2  | 501      | 'Grand-Royale'    -- change name
| 3  | 501      | 'Grand Royale 5*' -- change name
| 4  | 256      | 'Ocean Blue'

room_types
-----------------------------------------------------
| id | hotel_id | room_type_id   | room_name
-----------------------------------------------------
| 1  | 501      | 44             | 'Single'
| 2  | 501      | 44             | 'Single Standard' -- change name



 

То же самое относится к типам номеров и номерам. Таким образом, у меня есть первичный ключ id , Который отражает только номер записи, в то время как каждое свойство (имя, цена, адрес и т. Д.) Может измениться. Единственное , что не меняется, — это уникальные идентификаторы hotel_id , room_type_id и room_id

Я смог сделать все это, используя обычный java.sql.*, но теперь мне нужно переработать проект с помощью Spring Data JPA и Hibernate, и я совершенно не понимаю, как его сопоставить

 @Entity
@Table(name = "hotels")
public class Hotel { 
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   private Long id;

   @OneToMany(mappedBy = "hotel")
   private Set<RoomType> roomTypes; // ???

   ...
}

@Entity
@Table(name = "room_types")
public class RoomType {
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   private Long id;

   @ManyToOne
   @JoinColumn(name = "hotel_id", referencedColumn = "id") // ???
   private Hotel hotel;
   ...
}

 

Комментарии:

1. Вы повторяете данные внутри таблицы, и это плохая практика. Может быть, создать еще одну таблицу с именем «room_changes» и добавить изменения в каждую комнату, чтобы иметь запись о каждой из них?

Ответ №1:

Как насчет этого сопоставления?

 @Entity
@Table(name = "hotels")
public class Hotel { 
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   private Long id;

   @Column(name = "hotel_id, nullable = false, unique = true)
   private Long hotelId;

   @OneToMany(mappedBy = "hotel")
   private Set<RoomType> roomTypes;

   ...
}

@Entity
@Table(name = "room_types")
public class RoomType {
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   private Long id;

   @ManyToOne
   @JoinColumn(name = "hotel_id", referencedColumn = "hotel_id")
   private Hotel hotel;
   ...
}