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

Scenario: OneToOne Uni-directional [Optional]

In a Online auction/bidding system an item can bought by one user (one and only one user).

Data Modelling Perspective: Since a user can buy more than one item, so better to keep a FK in item table for buyer as BUYER_ID. But there are fair chances for this FK column being NULL either during the auction or the item was not bought even after auction was complete.

Such optional FK relations are best represented with a intermediate/join table.

So we can have a JOIN Table named like ITEM_BUYER with two columns ITEM_ID FK TO ITEM Table UNIQUE [ an item can be bought only once] BUYER_ID FK TO USER Table

Java Object Perspective: Item entity will have 2 references to User entity. One for buyer and another for seller.

Since association is uni-directional, User entity will not have any reference back to Item entity.

Entity classes:

@Entity @Table(name = "ITEMS") @Data @NoArgsConstructor @AllArgsConstructor @Builder @EqualsAndHashCode(of = {"itemId", "name"}, callSuper = false) @ToString public class Item {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ITEM_ID_SEQ")
@SequenceGenerator(name= "ITEM_ID_SEQ",
        sequenceName="ITEM_ID_SEQ",
        allocationSize = 1)
@Column(name = "ITEM_ID")
@JsonIgnore
private Long itemId;

@Column(name = "NAME")
private String name;

@Column(name = "INITIAL_AMOUNT")
private BigDecimal initialAmount;

// oneToOne uni-directional (non-optional)
@OneToOne
@JoinColumn(name = "SELLER_ID")
private User seller;

// oneToOne uni-directional (optional)
@OneToOne
@JoinTable(name = "ITEM_BUYER",
            joinColumns = @JoinColumn(name = "ITEM_ID_PK"/*, referencedColumnName = "itemId"*/),
            inverseJoinColumns = @JoinColumn(name = "BUYER_ID"/*, referencedColumnName = "id"*/))
private User buyer;

}


NO reference in User entity for Item entity, since association is uni-directional.

Persistence logic

@Override public void addBuyerToItem(ItemDTO itemDto) {

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

User user = userRepository.findOne(itemDto.getBuyerId());

item.setBuyer(user);

itemsRepository.save(item);

}