OneToMany | Bi directional | Optional - gauravsk89/hibernate GitHub Wiki
Scenario:
OneToMany Bidirectional (with Join Table)
In Online bidding system a user can buy 0..n items and an item can be bought by only once and by only one bidder.
Since there are chances that an item may not be bought at all, hence this association is optional. That's why we are using a Join table here.
USR
ID (PK)
FIRST_NAME NOT NULL
LAST_NAME NOT NULL
EMAIL_ID NOT NULL
ADDR_ID NOT NULL
ITEM
ID (PK)
NAME NOT NULL
INITIAL_AMOUNT NOT NULL
SELLER_ID NOT NULL
ITEM_BUYER
ITEM_ID (PK) [FK TO ITEM Table]
BUYER_ID NOT NULL [FK TO BID Table]
Entities:
User entity has a collection reference to bought Items
@OneToMany(mappedBy= "buyer", fetch= FetchType.EAGER, cascade = CascadeType.ALL)
private Set<Item> boughtItems;
Item entity has a reference back to User entity (buyer).
@OneToOne(fetch = FetchType.EAGER)
@JoinTable(name = "ITEM_BUYER",
joinColumns = @JoinColumn(name = "ITEM_ID"),
inverseJoinColumns = @JoinColumn(name = "BUYER_ID"))
private User buyer;
since a user can buy 0...n items, but a particular item can be bought by one and only one user. Hence using @OneToMany in User class and @OneToOne in Item class.
A convenience method has been added in Item entity to update the association between the two entities.
public void addBuyer(User buyer){
this.setBuyer(buyer);
if(buyer.getBoughtItems() == null){
buyer.setBoughtItems(new HashSet<>());
}
buyer.getBoughtItems().add(this);
}
Persistence Logic:
CRUD logic same as OneToMany Bidirectional with FK (without Join Table)
@Override
@Transactional
public void addBuyerToItem(ItemDTO itemDto) {
Item item = itemsRepository.findOne(itemDto.getItemId());
User user = userRepository.findOne(itemDto.getBuyerId());
item.addBuyer(user);
itemsRepository.save(item);
}