Today
-
Yesterday
-
Total
-
  • Spring boot: JPA 연관관계 살펴보기 - 1:N
    Spring Boot 🍃 2023. 12. 6. 00:01

    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=?

Designed by Tistory / Custom by 얼거스