OneToMany | Uni directional | (Optional) - gauravsk89/hibernate GitHub Wiki

Scenario:

Optional | OneToMany Unidirectional

In Online bidding system an item can have 0...n bids associated to it. And in this case association is kept as Unidirectional, but in real life in most cases it would be bi-directional (we may want to navigate to the item a bid belongs to).

Since this relation is a Optional one, so on database side a join table has been used to persist the association.

ITEM
	ID			(PK)
	NAME			NOT NULL
	INITIAL_AMOUNT		NOT NULL
	SELLER_ID		NOT NULL

BID
	ID			(PK)
	AMOUNT			NOT NULL
	
ITEM_BID_REL
	ITEM_ID			(PK) [FK TO ITEM Table]
	BID_ID			(PK) [FK TO BID Table]

Entities:

Item entity has a collection reference to Bids

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "ITEM_BID_REL", joinColumns = @JoinColumn(name = "ITEM_ID"),
            inverseJoinColumns = @JoinColumn(name = "BID_ID"))
private Set<Bid> bids;

Since this is uni-directional association and that too optional, so Bid entity has no reference back to Item class.

@JoinTable explained:

name : signifies the join table

joinColumns : tells name of the column that should be mapped with PK of this entity (entity inside which @JoinTable is defined)

inverseJoinColumns : tells name of the column that should be mapped with PK of other entity (entity defined with set Set i.e. Bid entity in this case)

So basically these name are not the names of entities, but these are the names of the columns of the Join table.

To test that if we swap the names in annotation like given below. @JoinTable(name = "ITEM_BID_REL", joinColumns = @JoinColumn(name = "BID_ID"), inverseJoinColumns = @JoinColumn(name = "ITEM_ID")) then swapped values will be inserted in database. In this case we have given "BID_ID" in "joinColumns" so what we try to say is that PK of Item entity i.e. ITEM_ID will be inserted into BID_ID column and "ITEM_ID" is given in "inverseJoinColumns" so what we try to say is that PK of inverse entity i.e. ID of Bid entity will be inserted into ITEM_ID column.

A convenience method has been added in Item entity to update the association between the two entities. public void addOrUpdateBids(Bid bid){ if(this.bids == null){ this.bids = new HashSet<>(); } this.getBids().add(bid); }

Persistence Logic:

@Override
@Transactional
public Item addBidToItem(BidDTO bidDTO) {

    Item item = itemsRepository.findOne(bidDTO.getItemId());

    Bid bid = Bid.builder()
                .bidAmount(bidDTO.getAmount())
                .build();

    item.addOrUpdateBids(bid);
    itemsRepository.save(item);

    return item;
}
⚠️ **GitHub.com Fallback** ⚠️