Learn one-to-many associations it’s and implementation
Introduction
- In this article, we will learn about the one-to-many association, when to use them, and implement them using Spring data JPA using one example.
One to Many Association
- Let’s understand the one-to-many association with a simple example. We have two entities/tables in the database. One is Customer and another is CreditCard.
- A Customer can have one or more CreditCard which defines the relationship between one to many.
- One-to-many relationships exist in the database when one row in the table has a relation with many rows in another table.
Entities
- Let’s define the necessary entities for our use case.
Customer
- In the customer entity, we need to define the @OneToMany relation where we define the List of CreditCard as a child association.
- This association will basically allow us access to all the CreditCard belonging to a given Customer entity.
@Entity
@Table(name="customer")
public class Customer {
@Id
@GeneratedValue(strategy= GenerationType.SEQUENCE, generator = "customer_id_seq")
@SequenceGenerator(name = "customer_id_seq", sequenceName = "customer_id_seq", allocationSize = 1)
private Long id;
private String name;
@OneToMany(mappedBy = "customer")
private List<CreditCard> creditCard = new ArrayList<>();
// getters and setters
}
- In our database, we have one customer for this use case.
Credit Card
- For the CreditCard entity we need to define @ManyToOne association with parent so that we can set up bidirectional relation.
- This will allow us to find the parent entity from the child entity. Basically, if we have a CreditCard entity we can get a Customer entity from it.
@Entity
@Table(name="credit_card")
public class CreditCard {
@Id
@GeneratedValue(strategy= GenerationType.SEQUENCE, generator = "credit_card_id_seq")
@SequenceGenerator(name = "credit_card_id_seq", sequenceName = "credit_card_id_seq", allocationSize = 1)
private Long id;
private String cardNumber;
private String expiryDate;
@ManyToOne
@JoinColumn(name="customer_id")
@JsonIgnore
private Customer customer;
}
- For our use case, we have two credit cards for the customer with id 10;
Business Logic
Repository
- For CustomerRepository and CreditCardRepository, All we need is to extend from JpaRepository.
- This will provide basic methods to execute queries on the database.
public interface CustomerRepository extends JpaRepository<Customer,Long> {
}
public interface CreditCardRepository extends JpaRepository<CreditCard,Long> {
}
Controller
- We have a rest endpoint that accepts the request param of customerId and returns the List of CreditCard as a response.
@RestController
@RequestMapping("/customer")
public class CustomerController {
@Autowired
private CustomerLogic customerLogic;
@GetMapping("/credit-card")
@ResponseBody()
private List<CreditCard> getAllCards(@RequestParam long customerId){
return customerLogic.getAllCards(customerId);
}
}
Logic
- Our logic gets the customer entity from customerId. Since we have a relation setup in the entity we can get the list of CreditCard for that customer.
public List<CreditCard> getAllCards(Long customerId){
Optional<Customer> customer = customerRepository.findById(customerId);
return customer.map(Customer::getCreditCard).orElse(null);
}
Result
- Let’s access the rest endpoint from the postman. We are passing customerId 10 as the request param.
- We received a list of CreditCard as a response.
Conclusion
- In this article, we learned about the one-to-many association with simple use cases.
- JPA provides abstractions that help in setting up unidirectional and bi-directional relationships.
Before You Leave
- Upgrade your Java skills with Grokking the Java Interview
- If you want to upskill your Java skills, you should definitely check out
[NEW] Master Spring Boot 3 & Spring Framework 6 with Java
[ 38 hrs content, 4.7/5 stars, 6+ students already enrolled]