본문 바로가기
JPA

[JPA] Entity 개발 시 참고 사항

by 코딩로그 2023. 2. 27.

@Builder 

 

@Builder를 쓰며 느꼈던 장점은 다음과 같습니다

1. 명시적 선언으로 각 파라미터가 어떤 의미인지 알기 쉬워 가독성 측면에서 훨씬 편했다.

2. 필요한 데이터만 설정할 수 있었다. 기존에는 해당 상황에 맞는 파라미터를 갖는 생성자들을 여러 개 생성했었는데, @Builder를 통해 필요한 파라미터 데이터만 설정할 수 있게 되었다.

 

 

 

특히, @Builder 어노테이션은 다음과 같이 두 가지 방식이 존재하고, 이중에 2번인 생성자에 @Builder 어노테이션 붙이는 방법을 사용하자!

=> 필요한 파라미터만 포함된 생성자에 @Builder 어노테이션을 붙이자!

 

 

 

1. 클래스에 @Builder 어노테이션 붙이기(X)

@Builder
public class User{
	...
}

 

2. 생성자에 @Builder 어노테이션 붙이기

    @Builder
    public User(int userId, String name) {
        this.userId = userId;
        this.name = name;
    }

 

 

 

 

Lazy Loading

 

 

다음과 같이 User, Team Entity가 있다.

@Entity
public class User{

    @ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private Team team;
    
}

 

@Entity
public class Team {

    @OneToMany(mappedBy = "team")
    private List<User> users = new ArrayList<>();
}

 

 

 

이때, 다음과 같이 Team과 User 객체를 각각 만들었다. 이후에 find() 메서드를 통해 User를 조회하는 예제 코드이다.

Team team = new Team();
team.setName("TeamA");
em.persist(team);

User user = new User();
user.setUsername("user1");
user.setTeam(team);

em.persist(user);

em.flush();
em.clear();

User findUser = em.find(User.class, user.getId());

 

 

이때, find() 함수를 통해 User를 조회하였다. 그러면, 당연히 내가 원하던 User에 대한 쿼리 결과가 나오겠다고 생각할 수 있다.

 

그런데,  다음과 같이 Team 테이블이 Join 되어서 조회 쿼리가 나옴을 알 수 있다. 

 

    select
        ...(생략)
    from
        User user0_ 
    left outer join
        Team team2_ 
            on user0_.TEAM_ID=team2_.TEAM_ID 
    where
        user0_.USER_ID=?

 

 

 

그렇다면, User만 조회하려면 어떡해야 할까???

 

 

다음과 같이 @ManyToOne 어노테이션에 fetch = FetchType.LAZY를 추가하자!!!

특히, @ManyToOne은 default가 FetchType.EAGER이므로 반드시 FetchType.LAZY를 추가해야 한다. 

@Entity
public class User{

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "TEAM_ID")
    private Team team;
    
}

 

 

FetchType.LAZY를 추가하면, 다음과 같이 원래 얻고자 했던 User만 조회할 수 있다.

    select
        ...(생략)
    from
        User user0_ 
    where
        user0_.USER_ID=?

 

 

 

특히, @ManyToOne, @OneToOne 은 FetchType.EAGER(즉시로딩)을 기본 전략(default)으로 사용하며,

@OneToMany, @ManyToMany 은 FetchType.Lazy(지연로딩)을 기본 전략(default)으로 사용한다.

 

 

 

 

 

@DynamicUpdate

 

개발하다 보면 실제로 변경되는 컬럼 데이터만 update 시켜야 할 때가 있다.

save 함수를 사용하면 수정된 데이터 컬럼만 수정되는 게 아니라 전체 컬럼을 수정하는 쿼리문이 발생되므로, 내가 모든 값을 세팅하지 않으면 null로 들어가 수정된다.

 

이때, @DynamicUpdate 어노테이션을 사용하면 null이 아닌 컬럼 데이터(수정된 데이터)만 Update 시킨다.

 

@DynamicUpdate
public class User{
	...
}

 

 

'JPA' 카테고리의 다른 글

[JPA] JPA 개념 정리  (0) 2023.01.15