Spring boot: JPA 연관관계 살펴보기 - 1:N

김아무개·2023년 6월 16일
0

Spring Boot 🍃

목록 보기
40/95

1:N 연관관계

한 쪽 엔티티가
관계를 맺은 엔티티 쪽의
여러 객체를 가질 수 있는 것을 의미한다.

@OneToMany 어노테이션 이용!

실습

user 엔티티에
user_id로 연관지어진
user history 데이터 목록을 가져오기

엔티티 설계

User 엔티티

public class User extends BaseEntity {

    private String name;
    private String email;

    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumn(
            name = "user_id" // 엔티티가 어떤 필드로 조인을 할지 지정해줌
            , 
            insertable = false, updatable = false // User 엔티티에서 UserHistory를 변경하지 못하도록 설정
    ) 
    private List<UserHistory> userHistories = new ArrayList<>(); // new ArrayList<>() = null point exception 방지
}

UserHistory 엔티티

이 엔티티에는 relation을 위한 설정을 따로 해주지 않았다.

한가지 짚고 넘어가야 할 부분이라면
User 엔티티 내부에서 JoinColumn으로 지정한 컬럼 이름에 대해
JPA가 처리할 때 관련 이름이 다수개일 수 있는 경우
( 컬럼으로 변환 될 필드 이름이 id인 경우도 해당 )

JoinColumn으로 지정한 컬럼 이름을
이 엔티티에서도 명확하게 지정해주는것이 좋다.

아래 코드에서는 @Column 어노테이션을 이용해서 해당되는 필드에 명시해주었다.

public class UserHistory extends BaseEntity{

    @Enumerated(EnumType.STRING) private UserStatus status;
    @Column(name = "user_id") 	 private Long userId;
    
    private String name;
    private String email;
    
    @Column(name = "USER_CREATED_AT") private LocalDateTime userCreatedAt;
    @Column(name = "USER_UPDATED_AT") private LocalDateTime userUpdatedAt;

}

test 코드 실행 확인

test 코드

@Test
void userRelationTest() {
	// new insert -> userHistory에 데이터 저장됨
    User user = User
            .builder()
            .name("zhyun")
            .email("gimwlgus@gmail.com")
            .gender(Gender.FEMALE)
            .build();
    userRepository.save(user);

	// update 1  -> userHistory에 데이터 저장됨
    user.setName("zzhyun");
    userRepository.save(user);

	// update 2  -> userHistory에 데이터 저장됨
    user.setEmail("zhyun@gmail.com");
    userRepository.save(user);

	// userRepository에서 history 조회
    List<UserHistory> result = userRepository
            .findByEmail("zhyun@gmail.com")
            .getUserHistories();
    result.forEach(System.out::println);
}

위의 코드에서

List<UserHistory> result = userRepository
         .findByEmail("zhyun@gmail.com")
         .getUserHistories();

코드는
아래의 코드와 같은 결과를 가져오게 된다.

List<UserHistory> result = userHistoryRepository
        .findByUserId(
                userRepository.findByEmail("zhyun@gmail.com").getId()
        );                                                            

jpa query 확인

test 코드에서 마지막 부분에 있는
userRepository에서 email 검색 후 history 데이터 가져오는 코드

Hibernate: 
    select
        u1_0.id,
        u1_0.created_at,
        u1_0.email,
        u1_0.name,
        u1_0.updated_at 
    from
        users u1_0 
    where
        u1_0.email=?
Hibernate: 
    select
        u1_0.user_id,
        u1_0.id,
        u1_0.created_at,
        u1_0.email,
        u1_0.name,
        u1_0.status,
        u1_0.updated_at,
        u1_0.user_created_at,
        u1_0.user_updated_at 
    from
        user_history u1_0 
    where
        u1_0.user_id=?
profile
Hello velog! 

0개의 댓글