I am learning jpa through some examples ,involving a shopping cart and cart items.I defined them as below..but am not very sure about which mapping to use
@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;
...
}
What I am not very sure of ,is how to relate between Product and CartItem
and how to set the mappedBy
attribute.Can somebody tell me how to do this?What are the criteria in doing this?I was trying to set something like 1 cartitem contains 1 product only
.It sounds like a OneToOne
relation.If so, who maintains the relation(is that not what mappedBy
does?).I have similar doubt about ShoppingCart
and CartItem
s too
thanks in advance
Association mappings are one of the key features of JPA and Hibernate. They model the relationship between two database tables as attributes in your domain model. That allows you to easily navigate the associations in your domain model and JPQL or Criteria queries.
The One-To-One mapping represents a single-valued association where an instance of one entity is associated with an instance of another entity. In this type of association one instance of source entity can be mapped atmost one instance of target entity.
One cart item references one product. But a single product is referenced by several cart items. So it's a one-to-many association.
One shopping cart as several items, and an item is part of one shopping cart, so it's also a one-to-many association.
When you have a bidirectional OneToMany association, the owner side of the association is always the many side. The owner side of an association is the side where there is no mappedBy
attribute. Indeed, mappedBy
means "I'm just the other side of an association, which is already mapped by the following attribute". Note that the way the asociation is mapped (join column, join table) must only be defined on the owner side, where the mappedBy
attribute is absent.
When you have a unidirectional association, there is only one place where the mapping can be defined, and the mappedBy attribute is thus never used.
So, your entities should be mapped like this:
@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;
...
}
If you want your cart item to know about its owning shopping cart, your association becomes bidirectional, and the entities become:
@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;
...
}
You ought to first decide whether you want a unidirectional or a bidirectional @OneToOne
relationship. A unidirectional relationship has an owning side (the side where the reference to another class is present), while a bidirectional relationship has both an owning side and an inverse side.
If you are declaring a unidirectional @OneToOne
relationship, then you do not need to worry about the mappedBy
attribute. For example, if you declare the Product
-CartItem
relationship as a unidirectional relationship with the CartItem
owning the relationship (and also possessing the foreign key in the database), then you merely need to annotate a reference to the Product
in the Product
class, as shown below; no changes are required in the Product
class:
@Entity
class CartItem{
private Long id;
@OneToOne
private Product product;
private int quantity;
...
}
If you need a bi-directional relationship, then you must define references that go both ways. In this case, you'll need to add a reference to a CartItem
from the Product
class. Furthermore, you'll need to specify the mappedBy
attribute on the inverse side, to refer to the owning side (the side that has the foreign key in the database), as shown below:
@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;
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With