One-to-Many Relationship Spring Data JPA

One-to-Many Relationship Spring Data JPA

ยท

3 min read

In this article, we will continue our learning about implementing relationships between entities in Spring Boot JPA. Today we will learn about implementing One-to-Many relationship.

One-to-Many Relationship

A one-to-many relationship is a type of cardinality that refers to the relationship between two entities A and B in which an element of A may be linked to many elements of B, but a member of B is linked to only one element of A.

Let's take an example of person and credit card, a person may have more than one credit card but one credit card is linked with only one person.

The person and passport classes are using Lombok to reduce boilerplate code, I suggest you to go through Lombok article .

Person.java

@Entity
@Table(name = "person")
@Getter @Setter @Builder
@NoArgsConstructor
@AllArgsConstructor
public class Person {

    @Id
    @Column(name = "person_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer personId;

    @Column(name = "person_name")
    private String personName;    

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(name = "person_card_mapping",
                joinColumns = @JoinColumn(name = "person_id"),
                inverseJoinColumns = @JoinColumn(name = "card_id"))
    private List<Card> cards;

}

Card.java

@Entity
@Table(name = "card")
@Getter @Setter @Builder
@NoArgsConstructor
@AllArgsConstructor
public class Card {

    @Id
    @Column(name = "card_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer cardId;

    @Column(name = "card_no")
    private String cardNo;

    @Column(name = "cardholder_name")
    private String cardholderName;

    @Column(name = "expiry_month")
    private String expiryMonth;

    @Column(name = "expiry_year")
    private String expiryYear;    
}

The relationship in the ER diagram is represented as follow:

image.png

The mapping is implemented in database using a mapping table which stores the primary key or identifying column from both the entities.

@JoinTable is used to specify the name of mapping table and joining column details.

name = "person_card_mapping" specifies the mapping table name where the primary keys will be stored.

joinColumns = @JoinColumn(name = "person_id") specifies that from person table person_id column will be used to implement mapping.

inverseJoinColumns = @JoinColumn(name = "card_id")) specifies that from card table card_id column will be used to implement mapping.

Testing

Let's see a test case to test the unidirectional one-to-many relationship between Person and Cards.

@SpringBootTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class OneToManyMappingTests {

    @Autowired
    private PersonRepository personRepo;

    private Person person = null;
    private Card card1 = null;
    private Card card2 = null;

    private Integer personId;

    @BeforeAll
    public void setup() {

        card1 = Card.builder()
                .cardholderName("John Doe")
                .cardNo("4578963214502354")
                .expiryMonth("12")
                .expiryYear("2022")
                .build();

        card2 = Card.builder()
                .cardholderName("John Doe")
                .cardNo("4111111111111111")
                .expiryMonth("02")
                .expiryYear("2025")
                .build();

        List<Card> cards = new ArrayList<>();
        cards.add(card1);
        cards.add(card2);

        person =  Person.builder()
                .personName("John Doe")
                .cards(cards)
                .build();

        person = personRepo.save(person);
        personId = person.getPersonId();
    }


    @Test
    public void testOneToMany() {

        Person person  = personRepo.findById(personId).orElse(null);

        assertNotNull(person.getCards());
        assertEquals("4578963214502354", person.getCards().get(0).getCardNo());
        assertEquals("4111111111111111", person.getCards().get(1).getCardNo());

    }

}

On running this test case, we will find all these test cases runs successfully and verifies that our implementation is correct.

Summary

In this article, we learnt about implementation of one-to-many mapping relationship in Spring Data JPA. The other mapping relationship in Spring Data JPA will be discussed in further post.

Check this article for implementing One-to-One mapping.

Check this article for implementing Many-to-Many mapping.

You can find the source code of this post @ Github

ย