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

weekbelt님의 프로필 이미지

작성한 질문수

스프링과 JPA 기반 웹 애플리케이션 개발

@ManyToMany에 관련된 질문입니다.

작성

·

344

1

안녕하세요. 백기선님의 강의를 실습해보면서 소모임이라는 웹 프로젝트를 따로 만들어 보는 중입니다.

강의에 해당하는 스터디 만들기를 실행했을 때

NullPointerException이 발생했고 제일 먼저  강의에서는 Study에 해당하는 엔티티인 Society엔티티의 addManager에서 에러가 발생했다는것은 알았는데  디버깅을 해보니

Society엔티티에서 managers에 new HashSet<>();으로 초기화를 했음에도 불구하고 null이 나왔습니다.

디버깅을 더 진행하였더니

TargetException으로 넘어갔는데 여기서부터 어떻게 해결해야 할지 모르겠습니다.

아래는 Society 엔티티이고 분명히 @ManyToMany의 연관관계를 맺은 부분에 new HashSet으로 초기화를 시켰는데 초기화되지 않고 null이 되는지 궁금합니다.

package me.weekbelt.runningflex.modules.society;

import lombok.*;
import me.weekbelt.runningflex.modules.account.Account;
import me.weekbelt.runningflex.modules.account.UserAccount;
import me.weekbelt.runningflex.modules.tag.Tag;
import me.weekbelt.runningflex.modules.zone.Zone;

import javax.persistence.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;

@Builder @AllArgsConstructor @NoArgsConstructor
@Getter @EqualsAndHashCode(of = "id")
@Entity
public class Society {

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

@ManyToMany
private Set<Account> managers = new HashSet<>();

@ManyToMany
private Set<Account> members = new HashSet<>();

@Column(unique = true)
private String path;

private String title;

private String shortDescription;

@Lob @Basic(fetch = FetchType.EAGER)
private String fullDescription;

@Lob @Basic(fetch = FetchType.EAGER)
private String image;

@ManyToMany
private Set<Tag> tags = new HashSet<>();

@ManyToMany
private Set<Zone> zones = new HashSet<>();

private LocalDateTime publishedDateTime;

private LocalDateTime closedDateTime;

private LocalDateTime recruitingUpdatedDateTime;

private boolean recruiting;

private boolean published;

private boolean closed;

private boolean useBanner;

public String getEncodedPath() {
return URLEncoder.encode(this.path, StandardCharsets.UTF_8);
}

public void addManager(Account account) {
this.managers.add(account);
}

public boolean isJoinable(UserAccount userAccount) {
Account account = userAccount.getAccount();
return this.isPublished() && this.isRecruiting()
&& !this.members.contains(account)
&& !this.managers.contains(account);
}

public boolean isMember(UserAccount userAccount) {
return this.members.contains(userAccount.getAccount());
}

public boolean isManager(UserAccount userAccount) {
return this.managers.contains(userAccount.getAccount());
}
}

답변 4

0

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

감사합니다! 해결했습니다. 클래스전체에 @Builder를 적용하지않고 엔티티에 따로 생성자를 만들어 @ManyToMany처럼 연관관계를 제외한 부분만 빌더 패턴으로 받을수 있게 했습니다.

0

백기선님의 프로필 이미지
백기선
지식공유자

@Builder.Default 를 사용해서 빌더 사용시 기본값을 설정할 수도 있긴 합니다.

@Builder.Default private final long created = System.currentTimeMillis();
이런식으로요.

https://projectlombok.org/features/Builder
참고하세요.

0

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

맞습니다. Setter를 쓰지 않기위해서 빌더를 써서 만들었는데 그렇다면 Setter를 사용하여 modelMapper를 이용해 바인딩해서 만드는 방법밖에 없는건가요?

@PostMapping("/new-society")
public String newSocietySubmit(@CurrentAccount Account account,
@Valid SocietyForm societyForm, Errors errors,
Model model) {
if (errors.hasErrors()) {
model.addAttribute("account", account);
return "society/form";
}

Society newSociety = Society.builder()
.path(societyForm.getPath())
.title(societyForm.getTitle())
.shortDescription(societyForm.getShortDescription())
.fullDescription(societyForm.getFullDescription())
.build();

Society society = societyService.createNewSociety(newSociety, account);
return "redirect:/society/" + society.getEncodedPath();
}

0

백기선님의 프로필 이미지
백기선
지식공유자

혹시 Society 객체를 만들 때 빌더를 사용해서 만들었다면 new HashSet()이 안되고 null 일겁니다.

weekbelt님의 프로필 이미지

작성한 질문수

질문하기