установка правильного сопоставления jpa для элементов корзины покупок и продукта

Я изучаю jpa на некоторых примерах, включающих корзину для покупок и элементы корзины. Я определил их, как показано ниже... но не очень уверен в том, какое сопоставление использовать.

@Entity
class Product{

   private Long id;
   private String name;
   ...
}

@Entity
class CartItem{
   private Long id;

   private Product product;

   private int quantity;

...
}

@Entity
class ShoppingCart{
   private Long id;

   @OneToMany
   private Set<CartItem> cartItems;

  ...
}

В чем я не очень уверен, так это в том, как связать Product and CartItem и как установить атрибут mappedBy. Может ли кто-нибудь сказать мне, как это сделать? Каковы критерии для этого? Я пытался установить что-то вроде 1 cartitem contains 1 product only. как отношение OneToOne. Если да, то кто поддерживает отношения (разве это не то, что делает mappedBy?). У меня тоже есть сомнения относительно ShoppingCart и CartItems

заранее спасибо


person jonlannister    schedule 05.09.2011    source источник


Ответы (2)


Один товар в корзине относится к одному товару. Но на один товар ссылаются несколько элементов корзины. Итак, это ассоциация «один ко многим».

Одна корзина как несколько товаров, а товар является частью одной корзины, так что это тоже ассоциация «один ко многим».

Если у вас есть двунаправленная ассоциация OneToMany, сторона владельца ассоциации всегда является стороной many. Сторона владельца ассоциации — это сторона, на которой нет атрибута mappedBy. Действительно, mappedBy означает "Я просто другая сторона ассоциации, которая уже отображена следующим атрибутом". Обратите внимание, что способ сопоставления ассоциации (столбец соединения, таблица соединения) должен быть определен только на стороне владельца, где атрибут mappedBy отсутствует.

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

Итак, ваши объекты должны быть отображены следующим образом:

@Entity
class Product{

   private Long id;
   private String name;
   ...
}

@Entity
class CartItem{
   private Long id;

   @ManyToOne
   private Product product;

   private int quantity;

...
}

@Entity
class ShoppingCart{
   private Long id;

   @OneToMany
   private Set<CartItem> cartItems;

  ...
}

Если вы хотите, чтобы ваш товар в корзине знал о том, что ему принадлежит корзина, ваша ассоциация становится двунаправленной, а объекты становятся:

@Entity
class CartItem{
   private Long id;

   @ManyToOne
   private Product product;

   @ManyToOne
   private ShppingCart shoppingCart;

   private int quantity;

...
}

@Entity
class ShoppingCart{
   private Long id;

   @OneToMany(mappedBy = "shoppingCart")
   private Set<CartItem> cartItems;

  ...
}
person JB Nizet    schedule 05.09.2011
comment
У меня есть пара (нубских) сомнений. В корзине я не хочу разрешать два элемента корзины, которые относятся к одному и тому же продукту. Если пользователь хочет купить больше одного и того же продукта, он может увеличить количество. Итак, это право давать ManyToOne между CartItem и Product? - person jonlannister; 05.09.2011
comment
Да. ManyToOne означает, что в корзине есть много товаров для одного и того же продукта. Тот факт, что не может быть несколько товаров в одной корзине для одного и того же продукта, здесь не имеет значения. Вы должны проверить это ограничение в коде Java и установить уникальное ограничение для [shopping_cart_id, product_id] в таблице элементов корзины. - person JB Nizet; 05.09.2011
comment
есть много товаров в корзине для одного и того же продукта. Имеет ли это смысл, учитывая, что доступно поле количества? Отношения OneToOne с полем количества кажутся мне более понятными. - person Alan Smith; 09.04.2018
comment
@AlanSmith, это было бы правдой, если бы была только одна корзина для покупок. Но магазин, в котором была бы только одна тележка для покупок, быстро обанкротился бы. Каждая корзина содержит множество элементов корзины, поэтому несколько элементов корзины могут ссылаться на один и тот же продукт (поскольку они просто являются частью разных корзин). - person JB Nizet; 09.04.2018
comment
@JB хорошо, теперь я тебя понимаю. Это через тележки. Спасибо. - person Alan Smith; 10.04.2018

Вы должны сначала решить, хотите ли вы однонаправленную или двунаправленную связь @OneToOne. У однонаправленного отношения есть сторона-владелец (сторона, на которой присутствует ссылка на другой класс), а у двунаправленного отношения есть как сторона-владелец, так и обратная сторона.

Если вы объявляете однонаправленную связь @OneToOne, вам не нужно беспокоиться об атрибуте mappedBy. Например, если вы объявляете связь Product-CartItem как однонаправленную связь с CartItem, владеющей связью (а также обладающей внешним ключом в базе данных), вам просто нужно аннотировать ссылку на Product в классе Product, как показано ниже; никаких изменений в классе Product не требуется:

@Entity
class CartItem{
   private Long id;

   @OneToOne
   private Product product;

   private int quantity;

...
}

Если вам нужна двунаправленная связь, вы должны определить ссылки, которые работают в обоих направлениях. В этом случае вам нужно будет добавить ссылку на CartItem из класса Product. Кроме того, вам нужно будет указать атрибут mappedBy на обратной стороне, чтобы сослаться на сторону-владельца (сторону, у которой есть внешний ключ в базе данных), как показано ниже:

@Entity
class Product{

   private Long id;
   private String name;
   @OneToOne(mappedBy="product") // the name of the property in the owning side
   private CartItem cartItem;
   ...
}

@Entity
class CartItem{
   private Long id;

   @OneToOne                    //the owning side
   private Product product;

   private int quantity;

...
}
person Vineet Reynolds    schedule 05.09.2011
comment
это OneToOne между CartItem и Product? JB Nizet считает, что это должно быть ManyToOne - person jonlannister; 05.09.2011
comment
Ну, это зависит от того, как вы хотите смоделировать отношения; ManyToOne будет означать, что на один Product можно ссылаться из нескольких CartItem (что, кажется, имеет смысл), в то время как OneToOne подразумевает, что на Product можно ссылаться только из одного CartItem одновременно. Кроме того, @ManyToOne оказывается обратным отношением @OneToMany, поэтому обычно легче думать о OneToMany, чтобы проверить, является ли обратное отношение ManyToOne. Наконец, вам нужно будет указать либо аннотацию для однонаправленной связи, либо обе для двунаправленной. - person Vineet Reynolds; 05.09.2011