Как смоделировать отношения ManyToOne и ManyToMany на одной и той же таблице в Hibernate? - PullRequest
0 голосов
/ 27 января 2020

Я хотел бы создать следующие отношения между таблицами

Таблицы -

  • Владелец - Таблица владельца содержит сведения о владельце.
  • DietPlans - Таблица DietPlans содержит все планы диеты, которые могут быть созданы владельцем. Владелец может создать n количество планов диеты, но каждый план диеты принадлежит одному владельцу. Таким образом, это отношение 1 к n или Один ко многим.
  • Клиент - Клиент - это, по сути, организация, которая использует планы диеты. Другими словами, я хочу, чтобы клиенты подписались на уже существующие планы диеты. Как я понимаю, подписка клиента на план диеты будет отношением «многие к одному». n количество клиентов могут подписаться на n количество планов диеты и наоборот. У клиента также есть отношения «многие к одному» с владельцем.

Итак, для реализации этих отношений у меня есть 2 подхода. Я хотел бы знать, какой из них будет работать лучше.

Подход 1 При таком подходе таблица DietPlans будет иметь отношение OneToMany к таблице Owner и отношение ManyToMany с таблицей клиентов.

Owner -

@Data
@Entity
public class Owner {

    @EmbeddedId
    private OwnerKey ownerId;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Customer> customers= new ArrayList<Customer>();


    @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Diet> dietPlans = new ArrayList<Diet>();
}

Customer таблица -

   @Data
    @Entity
    public class Customer{

        @EmbeddedId
        private CustomerKey customerId;

        @ManyToOne(fetch = FetchType.LAZY, optional= false)
        private Owner owner;

        @ManyToMany(fetch = FetchType.LAZY, mappedBy = "subscribedCustomers")
        private List<Diet> subscribedDietPlans = new ArrayList<Diet>();
    }

И планы Diet будут выглядеть следующим образом -

@Data
@Entity
public class Diet {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;


    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumns({
        @JoinColumn(.....
    })
    private Owner owner;

   @ManyToMany(fetch = FetchType.LAZY, optional = false)
    @JoinColumns({
        @JoinColumn.....)
    })
    private List<Customer> subscribedCustomers = new ArrayList<Customer>();

}

Клиенту не должно быть разрешено создавать какие-либо планы диеты, вместо этого просто подпишитесь на планы диеты , созданные его владельцем .

Подход 2 При таком подходе вместо связи «многие ко многим» между таблицей dietPlans и таблицей Customer я создам отдельную таблицу SubscribedPlans, которая будет содержать ссылку (внешний ключ) из таблицы DietPlans. Таблица SubscribedPlans будет иметь отношение «многие к одному» с таблицей клиентов. Таким образом, клиент не может подписаться на несуществующий план.

Какой из 2 лучше с точки зрения простоты? Кроме того, если есть лучший способ сделать это моделирование, пожалуйста, дайте мне знать.

1 Ответ

1 голос
/ 27 января 2020

Ответ на ваш вопрос будет зависеть от ответа на следующий вопрос

Считаете ли вы насущным требованием, когда вам потребуется разместить больше данных в подписанном плане пользователя? Например, скажем, продолжительность, в течение которой подписанный план будет активен, цены для плана и т. Д. c.

Если ответ «нет», то вам просто нужно сохранить сопоставление. В этом случае подход 1 работает лучше.

Если ответ положительный, вам нужно go с подходом 2. Поскольку объект SubscribedPlan будет развиваться и содержать подписанные пользователем детали, связанные с планом, такие как продолжительность , цена (это будет FK таблицы ценового плана) et c.

...