0
votes

I am trying to understand JPA OneToMany/ManyToOne. As of now precisely trying to understand mappedBy and JoinColumn.

My entities :


import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import javax.persistence.*;

@Entity
@Table(name = "mobile_number")
@Data
@ToString(exclude = "student")
public class MobileNumber {

    @Id
    private String number;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "student_id")
    private Student student;
}
package com.example.demo.entity;

import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.persistence.*;
import java.util.Set;

@Entity
@Table(name = "student")
@Data
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private String name;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "student")
    private Set<MobileNumber> mobileNumberSet;


}

My current understanding :

Here, MobileNumber is the owning side of relationship. And from that I understand that I can persist/fetch student entity using MobileNumber entity.

So if I simple write below code : |

 MobileNumber mn = new MobileNumber();
      mn.setNumber("some_number");

      Student s = new Student();
      s.setName("TestUser");
      
      mn.setStudent(s);
      mobileNumberRepository.save(mn);
  • It will automatically persist Student and do the mapping.
  • I can fetch MobileNumber Entity with a Student entity
  • If I fetch Student entity now, I will get set populated with the respective MobileNumbers Objects

Please help me if above points are correct

Areas of confusion :

I tried the other way as well trying persist Student :

Student s = new Student();
        s.setName("TestUser");
        MobileNumber mn = new MobileNumber();
        mn.setNumber("some_number");

        Set<MobileNumber> set = new HashSet<>();
        set.add(mn);
        s.setMobileNumberSet(set);

        studentRepository.save(s);

Now I dont understand, this behaves in unexpected ways. I could not see MobileNumber getting persisted at all.

Could anyone please help me how fetching and persisting of child entity (MobileNumber) works from this end.

Thanks

1

1 Answers

0
votes

When you deal with bidirectional one-to-many associations, you always have to keep associations in sync on both sides. From the Hibernate ORM documentation:

Whenever a bidirectional association is formed, the application developer must make sure both sides are in-sync at all times.

Your code should look like this:

        Student s = new Student();
        s.setName("TestUser");
        MobileNumber mn = new MobileNumber();
        mn.setNumber("some_number");
        mn.setStudent(s);

        Set<MobileNumber> set = new HashSet<>();
        set.add(mn);
        s.setMobileNumberSet(set);

        studentRepository.save(s);

Note, that you could also set the property hibernate.enhancer.enableAssociationManagement to true. This will enable Hibernate ORM bytecode enhancements and your previous code would have worked.