프로젝트를 하던도중 편의 메소드를 사용해야하는 상황이 생겼다. 이런 저런 시도를 해보았지만(나의 이해도부족)결국 성공하지 못하고 repository를 하나 더 만들어서 해결했다.(나중에는 편의메소드를 사용했지만)
삽질
- One
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
public class One {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "one")
private List<Many> manyList;
public One(String name) {
this.name = name;
}
}
- Many
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
public class Many {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
private One one;
private String name;
}
- 편의 메서드 사용
public class One {
...
public void addMany(Many many) {
manyList.add(many);
many.setOne(this);
}
}
public class Many {
...
public void setOne(One one) {
this.one = one;
}
}
public class OneRequest {
...
public One toOne() {
One one = new One(id, name);
for (ManyRequest request : manyList) {
one.addMany(request.toMany());
}
return one;
}
}
public class ManyRequest {
...
public Many toMany() {
return new Many(id, name);
}
}
이렇게 설정하고 request를 보내보면... 분명히 양쪽다 넣어줬는데 `One`만 저장된다
- 영속성 전이
나머지 코드는 다 똑같고
public class One{
...
@OneToMany(mappedBy = "one", cascade = CascadeType.PERSIST)
private List<Many> manyList = new ArrayList<>();
...
}
딱 이 부분만 다르게 했다.
그리고 request를 보내봣더니 저장이 잘 된다.
문제 원인
- 데이터 베이스의 cascade와 헷갈렸다
SimpleJpaRepository파일을 열어보면
JPA에서는 이런식으로 save를 할때 엔티티를 영속화 시켜주는데 이 과정에서 cascade가 없으면 자식 엔티티까지 영속화 하지 못한다. 그래서 저장이 안된것다..ㅜㅜ
편의 메소드 최적화
양방향 연관관계는 양 쪽 객체를 모두 신경써야 하는데, 하나의 메소드에서 양측에 관계를 설정하게 해주는 것이 안전하다. 이렇게 한번에 양방향 관계를 설정하는 메소드를 연관관계 편의 메소드라고 한다.
- 다대일측(User)에서 연관관계를 지정할 때 기존 연관관계는 끊어주어야 하고(one1 → one2 로 바꿀때 one1에 계속 남아있을 수 있다.), 무한 루프를 방지 해야한다.
public class One {
...
public void addMany(Many many) {
manyList.add(many);
if (many.getOne() != this) {
many.setOne(this);
}
}
}
public class Many {
...
public void setOne(One one) {
if (this.one != null) {
this.one.getManyList().remove(this);// 기존 연관관계 제거
}
this.one = one;
if (!one.getManyList().contains(this)) {// 무한루프 방지
one.addMany(this);
}
}
}
'트러블슈팅' 카테고리의 다른 글
연관관계 컬랙션 타입 관리 (1) | 2024.10.15 |
---|---|
Spring Batch processor 이야기 (0) | 2024.10.15 |
어노테이션 기반 권한 관리 (0) | 2024.10.14 |
관제값 조회 디자인 패턴 적용 (1) | 2024.10.13 |
그래프 조회 속도 개선 (1) | 2024.10.13 |