인프런 커뮤니티 질문&답변

gotjd9773님의 프로필 이미지
gotjd9773

작성한 질문수

입문자를 위한 Spring Boot with Kotlin - 나만의 포트폴리오 사이트 만들기

[실습] 데이터베이스 초기화

ProjectSkill은 데이터가 안들어가고 있습니다.

해결된 질문

작성

·

257

1

안녕하세요. 데이터베이스 초기화에서 질문 남깁니다.

현재 Project 엔티티에서 ProjectSkill 간의 참조가 아래와 같습니다.
@OneToMany(mappedBy = "project") var skills: MutableList<ProjectSkill> = mutableListOf()

위 관계는 project_skill 테이블이 연관관계의 주인이 되고, Project 엔티티는 그저 거울(mappedBy 속성에 의해)이 되는 걸로 알고 있습니다.

위 상태에서는 project.skills.addAll() 로 값을 넣어줘도 project_skill 테이블에 데이터가 들어가지 않고 projectSkill을 직접 save해줘야 insert 쿼리가 날아가는 것으로 알고 있습니다.

그러나 DataInitializer에서는 project.skills.addAll()로 넣어주고 있습니다.

그래서 실제로 데이터베이스를 확인해보면 project_skill 테이블에는 값이 들어가지 않고 있는 걸 확인할 수 있습니다.

다른 테이블에는 의도한대로 데이터베이스 들어가는 반면에 말입니다.

혹시 제가 잘못 알고 있는 거라면 바로잡아주시길 바랍니다.

답변 2

1

정보근님의 프로필 이미지
정보근
지식공유자

안녕하세요 정보근입니다:)

JPA 이해도가 높아보이는 좋은 질문이네요.

 

결론부터 말씀드리면 잘못 알고 계신 것은 없습니다.

다만 강의노트나 깃허브 리포지토리에서 "엔티티 개발 - 연관관계 있음" 부분을 보시면,

project의 @OneToMany에 cascade = [CascadeType.PERSIST] 옵션이 지정되어 있는데요.

gotjd9773님이 테스트 하신 코드에는 이 옵션이 안 들어가있었을 것으로 생각됩니다.

위와 같이 옵션을 지정하면 해당 엔티티가 "영속" 상태가 될 때 매핑된 엔티티도 같이 영속 상태가 됩니다.

이렇게 지정한 이유는 project_skill이 그 자체로 의미를 가지지 않은 단순한 매핑 테이블이기 때문입니다.

주로 사용하게 되는 엔티티는 project이기 때문에 편의성을 위해 persist에 한해서 영속성을 연결해준거죠.

 

다시 한 번 정리하면 주인이 아닌, 즉 mappedBy가 있는 "일" 쪽에 "다"를 추가하해도 "다"가 저장되지는 않습니다.

하지만 cascade를 쓰면 지정된 타입에 따라 "다"도 같이 영속성 상태가 변경이 됩니다.

따라서 Project 엔티티에 cascade를 추가해주면 인서트도 정상적으로 실행될 겁니다.

 

아래 간단한 코드 첨부드리니 팀과 멤버에 각각 cascade를 넣어보기도, 빼보기도 하고

팀만 저장하기도, 멤버만 저장하기도 하면서 어떻게 결과가 나오는지 직접 확인하시면

이해에 더 도움이 될 것으로 생각되네요.

@Entity
class Team() {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "team_id")
    var id: Long? = null

    var name: String? = null

    @OneToMany(mappedBy = "team", fetch = FetchType.LAZY, cascade = [CascadeType.PERSIST])
    var members: MutableList<Member> = mutableListOf()
}

@Entity
class Member() {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "member_id")
    var id: Long? = null

    var name: String? = null

    @ManyToOne(targetEntity = Team::class, fetch = FetchType.LAZY)
    @JoinColumn(name = "team_id", nullable = false)
    var team:Team?= null

}


// 샘플 테스트 코드
var team1 = Team()
team1.name = "team1"

var member1 = Member()
member1.name="a"
member1.team = team1
// memberRepository.save(member1)

team1.members.add(member1)
teamRepository.save(team1)

 

감사합니다.

 

 

0

gotjd9773님의 프로필 이미지
gotjd9773
질문자

아 제가 cascade 옵션을 안 넣어줬던거군요.

덕분에 해결되었어요!
답변 감사드립니다.

 

gotjd9773님의 프로필 이미지
gotjd9773

작성한 질문수

질문하기