부자 되기 위한 블로그, 머니킹

 

1. 코드상황

Profile.class

package com.jelly_develop.passprofile.domain.profile;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.Setter;

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

@Entity
@Getter
@Setter
public class Profile {
    @Id
    @GeneratedValue
    @Column(name = "profile_id")
    private Long id;
    @Column(name = "profile_title")
    private String title;
    @Column(name = "profile_password")
    private String password;

    @OneToMany(mappedBy = "profile")
    private List<ProfileBlock> profileBlocks;

    // == 연관관계 메서드 == //
    public void addProfileBlock(ProfileBlock profileBlock) {
        profileBlocks.add(profileBlock);
        profileBlock.setProfile(this);
    }
}

 

ProfileBlock.class

package com.jelly_develop.passprofile.domain.profile;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

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

@Entity
@Getter @Setter
@NoArgsConstructor
public class ProfileBlock {

    @Id @GeneratedValue
    @Column(name = "profile_b_id")
    private Long id;

    @Column(name = "profile_b_name")
    private String name;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "profile_id")
    private Profile profile;

    public ProfileBlock(String name) {
        this.name = name;
    }

}

 

ProfileController.class 일부부분

@PostConstruct
    @Transactional
    public void init() {
        log.info("profile controller init");

        for (int i = 0; i < 10; i++) {
            Profile profile = new Profile();
            profile.setTitle("test" + Integer.toString(i));
            profile.setPassword("test" + Integer.toString(i));
            
//          Profile Block 생성
            for(int j =0;j<4;j++){
                ProfileBlock profileBlock = new ProfileBlock("test" + Integer.toString(i)+"-"+ Integer.toString(j));
                profileBlock.setProfile(profile);
            }
            
            profileRepository.save(profile);
        }

    }

 

원리를 보니 연관관계로 등록될 때 자동으로 영속성 컨텍스트에 추가하는데

 

위같은 코드는 profileBlock의 set 함수를 통해 profile을 저장할 때 마다 영속성 컨택스트에 추가되는것이다

 

예를 들어 첫번째 반복문에 profileBlock1 의 set 함수를 통해 profile이 두번째 반복문에도 똑같은 profile이 등록되어 충돌이 일어난다.

 

이를 방지하기 위해 profile을 먼저 영속성 컨택스트에 등록해준다.

 

ProfileController.class 수정부분

@PostConstruct
@Transactional
public void init() {
    log.info("profile controller init");
    

    for (int i = 0; i < 10; i++) {
        Profile profile = new Profile();
        profile.setTitle("test" + Integer.toString(i));
        profile.setPassword("test" + Integer.toString(i));
        profileRepository.save(profile);

        for(int j =0;j<4;j++){
            ProfileBlock profileBlock = new ProfileBlock("test" + Integer.toString(i)+"-"+ Integer.toString(j));
            profileBlock.setProfile(profile);
            profileBlockRepository.save(profileBlock);
        }
    }

}