@JoinColumn은 왜 사용할까요?
외래키 만드려고 사용해줍니다.
그런데 테이블과는 다르게 객체에서는 참조하는 테이블의 pk가 아닌, 참조 객체 그 잡채를 외래키로 작성하잖아요? 즉 DB와 다른 방식을 사용하는 것이므로 무언가 처리가 필요합니다.
그리고 그 처리를 해주는게 JPA 인데,
JPA는 우리가 참조 객체를 써주면 자동으로 해당 객체의 pk를 찾아서 DB에 외래키로 작성해줍니다. (그래서 JPA를 ORM 기술이라고도 부르죵.)
기본적으로, JPA가 생성해주는 외래키 이름(name)은 "참조 필드 이름_참조하는 객체의 pk"예요.
근데 우리가 기본으로 생성해주는 외래키 이름말고, 다른 이름으로 바꿔서 테이블에 저장하고 싶을 수 있져? 그때 쓰라고 나온게 name 속성입니다.
name 속성 알아보기
public class Reservation extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
}
위처럼 작성하면 user_id라는 외래키 필드가 Reservation 테이블에 저장됩니다.
public class Reservation extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_pk")
private User user;
}
그래서 만약 위처럼 작성하면, "user_pk"가 Reservation 테이블에 저장되어요.
*만약 JPA가 만들어주는 기본 외래키 필드의 이름인 "참조하는 엔티티 이름_id"를 사용하고 싶다면, name 속성을 생략해도 됩니다.
referencedColumnName 속성
name 속성을 설명할 때 했던 말을 기억하시나요?
JPA는 우리가 참조 객체를 써주면 자동으로 해당 객체의 pk를 찾아서 DB에 외래키로 작성해줍니다.
기본적으로, JPA가 생성해주는 외래키 이름(name)은 "참조 필드 이름_참조하는 객체의 pk"예요.
referencedColumnName 속성을 지정해주면,
" 우리가 참조 객체 써주면 자동으로 해당 객체의 pk를 찾아서 " 가 아닌
" 우리가 참조 객체 써주면 해당 객체에서 referencedColumnName 으로 작성한 필드를 찾은 다음 외래키로 지정" 이 됩니다.
JPA가 자동으로 지정해주던 참조객체의 pk를 우리가 수동으로 지정해주는거죠.
그래서 다음과 같은 코드는 오류가 발생합니다.
public class Reservation extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", referencedColumnName = "thisIsGura")
private User user;
}
(물론 User 엔티티에 thisIsGura라는 필드가 없다는 가정하에 말이죠!!)
여기서, referencedColumnName 을 통해서 아무 필드나 외래키 지정이 가능할까?
이에 대한 chapGPT4의 답변은 아래와 같습니다.
중요한 것은, referencedColumnName으로 지정된 필드는 해당 엔티티의 유일한 식별자(unique identifier)로 사용될 수 있어야 합니다.
반드시 @Id가 붙어 있는 필드일 필요는 없지만, 데이터베이스 관점에서 해당 필드가 유일한 값을 가지고 있어야 한다는 조건은 충족되어야 합니다. 예를 들어, @Id가 아닌 필드에 @Column(unique = true)를 설정하여 유일성을 보장할 수도 있습니다.
결론적으로, referencedColumnName을 사용해 아무 필드나 외래키로 지정하는 것은 기술적으로 가능하지만, 그 필드가 유일한 값을 갖도록 하는 것이 중요합니다. 만약 @Id가 붙지 않은 필드를 사용한다면, 해당 필드가 엔티티 내에서 유일한 값을 가지고 있어야 하며, 이는 데이터의 일관성과 무결성을 유지하기 위한 조건입니다.
아니어도 되긴한다고 한다! 그러나 조심해서 사용할 것~ 이라는 지피티씨의 말이다.
참고
https://resilient-923.tistory.com/416
'Spring > 스프링 Data JPA' 카테고리의 다른 글
연관관계 편의 메서드는 왜 작성해야할까? (0) | 2024.01.17 |
---|---|
@Builder,@NoArgsConstructor(AccessLevel.PROTECTED),@AllArgsConstructor (0) | 2024.01.16 |