πŸ‘€ ν˜„μž¬ 상황 및 λ°°κ²½ μ„€λͺ…

ν˜„μž¬ ν”„λ‘œμ νŠΈμ—μ„œ Builder νŒ¨ν„΄μ„ μ‚¬μš©ν•˜μ—¬ μ—”ν‹°ν‹° 객체λ₯Ό μƒμ„±ν•˜κ³  있으며, 특히 μ–‘λ°©ν–₯ 연관관계λ₯Ό μ„€μ •ν•œ Organization μ—”ν‹°ν‹°μ—μ„œ 리슀트 ν˜•νƒœμ˜ μ»¬λ ‰μ…˜ ν•„λ“œλ₯Ό μ‚¬μš©ν•˜κ³  μžˆλ‹€.

 

β–Ά κ΅¬ν˜„ μ½”λ“œ

@Entity
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class Organization {

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


	...


    // μ–‘λ°©ν–₯ 연관관계
    @OneToMany(mappedBy = "organization", cascade = CascadeType.REMOVE, orphanRemoval = true)
    private List<OrganizationMember> organizationMembers = new ArrayList<>();

    // 연관관계 편의 λ©”μ„œλ“œ - μΆ”κ°€
    public void addOrganizationMember(OrganizationMember organizationMember) {
        this.organizationMembers.add(organizationMember);
    }

    // 연관관계 편의 λ©”μ„œλ“œ - μ‚­μ œ
    public void removeOrganizationMember(OrganizationMember organizationMember) {
        this.organizationMembers.remove(organizationMember);
    }
}
 

 

🚨 문제 상황

μ–‘λ°©ν–₯ 연관관계λ₯Ό μ„€μ •ν•˜λ©΄μ„œ organizationMembers 리슀트λ₯Ό new ArrayList<>()둜 μ΄ˆκΈ°ν™”ν–ˆμŒμ—λ„ λΆˆκ΅¬ν•˜κ³  NullPointerException이 λ°œμƒν•˜λŠ” λ¬Έμ œκ°€ μžˆμ—ˆλ‹€.

 

 

✏️ μ›μΈ 뢄석

Builder νŒ¨ν„΄μ„ μ‚¬μš©ν•  λ•Œ, λ¦¬μŠ€νŠΈλ‚˜ μ»¬λ ‰μ…˜κ³Ό 같은 ν•„λ“œλŠ” 기본적으둜 μ΄ˆκΈ°ν™”λ˜μ§€ μ•ŠλŠ”λ‹€. 이둜 인해 μ»¬λ ‰μ…˜ ν•„λ“œκ°€ null μƒνƒœλ‘œ μœ μ§€λ˜μ–΄ 연관관계 편의 λ©”μ„œλ“œμ—μ„œ add() 호좜 μ‹œ μ—λŸ¬κ°€ λ°œμƒν•œ 것이닀.

 

 

πŸ”¨ ν•΄κ²° 방법

Builderλ₯Ό μ‚¬μš©ν•˜λ©΄μ„œ μ΄ˆκΈ°ν™”κ°€ ν•„μš”ν•œ ν•„λ“œμ—λŠ” @Builder.Defaultλ₯Ό μ‚¬μš©ν•˜μ—¬ 기본값을 λͺ…μ‹œμ μœΌλ‘œ μ„€μ •ν•΄ μ£Όμ–΄μ•Ό ν•œλ‹€.

@Entity
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class Organization {

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


	...


    // μ–‘λ°©ν–₯ 연관관계
    @Builder.Default // 리슀트 κΈ°λ³Έκ°’ μ΄ˆκΈ°ν™”
    @OneToMany(mappedBy = "organization", cascade = CascadeType.REMOVE, orphanRemoval = true)
    private List<OrganizationMember> organizationMembers = new ArrayList<>();

    // 연관관계 편의 λ©”μ„œλ“œ - μΆ”κ°€
    public void addOrganizationMember(OrganizationMember organizationMember) {
        this.organizationMembers.add(organizationMember);
    }

    // 연관관계 편의 λ©”μ„œλ“œ - μ‚­μ œ
    public void removeOrganizationMember(OrganizationMember organizationMember) {
        this.organizationMembers.remove(organizationMember);
    }
}

 

 

πŸ” κ²°κ³Ό κ΄€μ°°

λ¬Έμ œκ°€ ν•΄κ²°λ˜μ—ˆμœΌλ©°, μ»¬λ ‰μ…˜ ν•„λ“œκ°€ μ •μƒμ μœΌλ‘œ μ΄ˆκΈ°ν™”λ˜μ–΄ NullPointerException 없이 λ¦¬μŠ€νŠΈμ— 데이터λ₯Ό μΆ”κ°€ν•˜κ±°λ‚˜ μ‚­μ œν•  수 있게 λ˜μ—ˆλ‹€.

쿼리가 μ •μƒμ μœΌλ‘œ μ‹€ν–‰λ˜λŠ” 것을 확인할 수 μžˆλ‹€!

 

 

πŸ’‘ κ³ μ°°

Builder νŒ¨ν„΄μ€ 가독성과 μœ μ—°μ„±μ„ μ œκ³΅ν•˜μ§€λ§Œ, μ»¬λ ‰μ…˜κ³Ό 같은 ν•„λ“œλŠ” μžλ™μœΌλ‘œ μ΄ˆκΈ°ν™”λ˜μ§€ μ•ŠλŠ”λ‹€λŠ” 점을 μ£Όμ˜ν•΄μ•Ό ν•œλ‹€. @Builder.Defaultλ₯Ό 적절히 μ‚¬μš©ν•¨μœΌλ‘œμ¨ μ΄λŸ¬ν•œ 문제λ₯Ό λ°©μ§€ν•  수 μžˆλ‹€. 이번 문제λ₯Ό 톡해 개발 λ„κ΅¬μ˜ λ™μž‘ 방식을 μΆ©λΆ„νžˆ μ΄ν•΄ν•˜κ³  μ‚¬μš©ν•˜λŠ” 것이 μ€‘μš”ν•˜λ‹€λŠ” 점을 λ‹€μ‹œ ν•œλ²ˆ λŠκΌˆλ‹€. μ•žμœΌλ‘œλŠ” νŽΈλ¦¬ν•œ κΈ°λŠ₯듀을 μ‚¬μš©ν•  λ•Œ κ·Έ λ‚΄λΆ€ λ™μž‘μ„ λͺ…ν™•νžˆ μ΄ν•΄ν•˜λŠ” μŠ΅κ΄€μ„ κΈ°λ₯΄λ €κ³  ν•œλ‹€.

 
 

πŸ“ μ°Έκ³  자료

soeun2537