728x90
@OneToOne ( 1:1 ) 매핑을 하면 데이터 입력 시 1:1 을 보장할까??
위의 내용에 대해 테스트를 해보았다.
Member 클래스, Locker 클래스가 있다.
조건은 Member 1명당 1개의 Locker만 사용할 수 있다.
Member 클래스가 연관관계의 주인이 되며, Locker 클래스에서는 mappedBy를 사용해 양방향으로 연결해준다.
테스트 내용 : 1명의 락커에 1명 이상의 멤버가 들어가는지 확인한다.
public class Member {
@Id
@GeneratedValue
@Column(name = "member_id")
private Long id;
private String username;
@OneToOne
@JoinColumn(name = "locker_id")
private Locker locker;
}
public class Locker {
@Id @GeneratedValue
@Column(name = "locker_id")
private Long id;
private String name;
@OneToOne(mappedBy = "locker")
private Member member;
}
락커 1개를 생성해주었으며, 멤버는 2명을 생성해주었다.
멤버 1과 2에 모두 동일한 락커를 세팅해주고 실행해보았다.
Locker locker = new Locker(); // 락커 1개 생성
locker.setName("Locker1");
em.persist(locker);
Member member = new Member(); // member1 생성
member.setUsername("member1");
member.setLocker(locker); // 라커 1 지정
em.persist(member);
Member member2 = new Member(); // member2 생성
member2.setUsername("member2");
member2.setLocker(locker); // 라커 1 지정
em.persist(member2);
결과를 확인해보면 @OneToOne 관계임에도 불구하고 1:1 매핑이 이루어지지 않았다.
@OneToOne은 < @OneToOne ( 1:1 ) 매핑을 하면 데이터 입력 시 1:1 을 보장할까? >
라는 조건이 틀리다 라는 것을 알 수 있다.
그러면 1:1 로 매핑 ( member1 - locker1 가능 / member2 - locker1 실패 ) 하기 위해서는 어떻게 해야할까?
바로 Member 테이블의 locker 에 unique 제약조건을 추가해 조건을 만족시킬 수 있다.
public class Member {
@Id
@GeneratedValue
@Column(name = "member_id")
private Long id;
private String username;
@OneToOne
// unique 제약조건 추가
@JoinColumn(name = "locker_id", unique = true)
private Locker locker;
}
테스트를 해보자
콘솔에 unique 로 인해 에러가 발생한것을 확인할 수 있으며, DB 에서도 추가되지 않은 것을 확인할 수 있다.
728x90
'Spring > JPA' 카테고리의 다른 글
JPA 순환 참조 해결해보기 (0) | 2022.11.30 |
---|---|
data.sql 적용하기 (스프링부트 버전 2.7.x 이상 ) (0) | 2022.11.10 |
Where 다중 파라미터 사용 - 동적쿼리 (0) | 2022.10.12 |
BooleanBuilder - 동적 쿼리 (0) | 2022.10.12 |
JPQL 과 QueryDsl 의 차이 (기초) (0) | 2022.10.09 |
댓글