SMALL

JPA의 연관관계 매핑의 다중성 중에 하나인 One To Many Mapping에 관해서 알아보고 예시를 보도록 하자.

연관관계 관련 어노테이션 중에 @OneToMany, @ManyToOne이 존재한다.

언뜻 보면 두 어노테이션은 같은 기능을 할 것 같지만 그렇지 않다. 

 

예시로 학생과 수업 Entity를 살펴보자.

학생은 여러 개의 수업을 수강할 수 있지만, 수업은 한 명의 학생만 수강할 수 있다. (과외라고 생각하자)

이 관계에서 주인은 foreign key를 가지고 있는 Courses가 된다.

 


@Getter
@NoArgsConstructor
@Entity
public class Courses {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;

	@Column
	private String name;

	@ManyToOne
	private Students student;

	@Builder
	public Courses(String name) {
		this.name = name;
	}

	public void update(String name, Students student) {
		this.name = name;
		this.student = student;
	}
}

 

@Getter
@NoArgsConstructor
@Entity
public class Students {

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

	@Column
	private String name;

	@Builder
	public Students(String name) {
		this.name = name;
		this.course = new HashSet<>();
	}

	public void update(String name, Courses course) {
		this.name = name;
		this.course.add(course);
	}
}

이러한 형태로 Entity를 작성하게 되면, Course에 Student_ID에 해당하는 foreign key가 생성된다.

( 대부분 연관관계의 주인이 foreign key를 가지고 있다고 생각하면 된다)

지금 현재 상태에서는 Students에서 자신이 수강하고 있는 Courses의 정보를 조회하기 어렵다.

이러한 점을 보완하기 위해 양방향 매핑으로 코드를 추가해보자.

 

양방향 관계

@Getter
@NoArgsConstructor
@Entity
public class Students {

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

	@Column
	private String name;

	@OneToMany(mappedBy = "student") //ADDED !
	private Set<Courses> course;

	@Builder
	public Students(String name) {
		this.name = name;
		this.course = new HashSet<>();
	}

	public void update(String name, Courses course) {
		this.name = name;
		this.course.add(course);
	}
}

@OneToMany 어노테이션을 가진 courseSet이 해당 매핑 관계의 주인이 아닌것을 표시하기 위해 mappedBy를 추가한다.

 

 

테스트 코드

위의 관계를 확인하는 테스트 코드를 보자.

    @Test
    public void 코스와학생매핑_OneToMany_코스가주인() {
    	
        Courses course = Courses.builder().name("METH").build();
        Courses courseEng = Courses.builder().name("ENG").build();
        Students student = Students.builder().name("Jon").build();
        
        studentsRepository.save(student);
        
        course.updateStudent(student); // Mapping Courses With Students
        courseEng.updateStudent(student); // Mapping Courses With Students
        
        coursesRepository.save(course);
        coursesRepository.save(courseEng);

        assertThat(course.getStudent().getId()).isNotNull();
    }

 

 

LIST

+ Recent posts