문제를 발견하게 된 과정
테이블 A, B 가 연관관계 매핑이 돼있고, B가 널인 상태일때,
서비스에서 A, B를 저장하고, flush를 한 후, A를 이용해서 B를 가져오면 널을 가져오게 됩니다. => 문제상황
하지만, 만약 B가 널이 아닌 상태에서 A를 이용해 B를 가져오면 널이 아닌 객체를 잘 가져옵니다.
@Table
@Entity
@Getter
@Builder
public class A {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToOne(mappedBy ="A")
private B b;
}
@Table
@Entity
@Getter
@Builder
public class B {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@MapsId
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "id", nullable = false)
private A a;
}
// 서비스 코드
@Service
@Transactional
@RequiredArgsConstructor
public class Service {
private ARepository aRepository;
public Test(){
// A, B 저장
aRepository.flush();
A a = aRepository.selectByName(name);
String name = a.getB().name();
}
}
// 레포지토리 코드
// 여기서 메서드를 통해 가져올 코드는 모두 매핑이 돼있고, 널이 아닌 entity 라고 가정합니다.
@Repository
public class ARepositoryImpl implements ARepositoryCustom {
...
@Override
public A selectByName(String name) {
return queryFactory.selectFrom(a)
.leftJoin(a.B, b)
.fetchJoin()
.where(a.name.eq(name))
.fetch();
}
}
문제해결을 위해 시도해본 방법들
ChatGPT에 물어봤습니다..
1. 연관관계를 올바르게 설정했는지
2. 영속성 전이를 설정했는지 cascade (연관관계 주인인 엔티티에 cascade옵션을 추가하면 종 엔티티의 저장을 자동으로 처리할 수 있습니다.)
3. 1개의 트랜젝션에서 작업했는지
4. 데이터베이스 제약조건에서 외래 키 제약조건이 설정돼 저장이 안된건 아닌지
확인해봤습니다.
문제의 원인
A엔티티는 @OneToOne(mappedBy = "A") 어노테이션이 설정되어 있으므로 연관관계의 주인이 아닙니다.
따라서 A, B 객체를 저장할 때 B와의 연관관계를 설정해야 합니다.
@Service
@Transactional
@RequiredArgsConstructor
public class Service {
private ARepository aRepository;
private BRepository bRepository;
public Test(){
A a = A.builder()
.name("A")
.build();
B b = B.builder()
.name("B")
.a(a)
.build();
a.setB(b); // A와 B의 양방향 연관관계 설정
bRepository.save(b);
aRepository.save(a);
aRepository.flush();
String name = a.getB().getName();
}
}
문제를 해결한 방법
저장 로직을 바꿔서 flush()를 사용하지 않는 방법으로 수정했습니다.
반응형
'Coding > trouble shooting' 카테고리의 다른 글
BUG | MsSql Deadlock 교착상태 문제 해결 (0) | 2024.10.28 |
---|---|
BUG | Mapstruct NullPointerException because "sym" is null (0) | 2023.07.10 |
BUG | DB 커넥션 부족 문제 해결 비결 (1) | 2023.06.01 |