https://lkhlkh23.tistory.com/159
https://thorben-janssen.com/lombok-hibernate-how-to-avoid-common-pitfalls/
https://levelup.gitconnected.com/be-careful-with-lombok-2e2edfc01110
https://medium.com/@vgonzalo/dont-use-lombok-672418daa819
Lombok 은 자바개발자에게서 매우 유명한 프레임워크다. 자바의 기본 메소드들인 getter,setter, equals,hashCode, 생성자들을 만들어준다. 어노테이션 몇개만 채워주게 되면 클래스들의 번거로운 메소드들을 컴파일 시에 자동으로 추가되게 해준다.
하지만, 만약 hibernate Entity 를 사용할 때에는 몇가지 함정에 빠질 수 있다. 이런 함정에 빠지지 않기 위해서는 이런 경우에 Lombok 을 쓰기보단, 여러분이 쓰는 IDE 의 힘을 빌려 메서드들을 구현하는 것이 더 낫다.
롬복은 어노테이션 하나만으로 클래스에 필수적인 생성자를 자동으로 생성해준다.
아래 테스트를 통해, 내가 직접 생성자를 만드는 것과 롬복을 이용해 생성자를 만드는 것에 차이는 없어보인다.
class CoreApplicationTests {
public static class Member1 {
private String name;
private String team;
private int age;
public Member1(String name, String team, int age) {
this.name = name;
this.team = team;
this.age = age;
}
}
@AllArgsConstructor
public static class Member2 {
private String name;
private String team;
private int age;
}
// 롬복에 의해 생성자가 생성되었으므로 어떤 예외도 없다
@Test
void test() {
Assertions.assertThatNoException().isThrownBy(()->{
Member1 member1 = new Member1("11st","CX",27);
Member2 member2 = new Member2("11st","CX",27);
});
}
}
여기서 함정은, 편리하게 생성된 생성자가, 필드의 위치 변화에까지 민감하게 반응한다는 것에 있다.
무슨 말인지 살펴보자.
만약 Member2의 field 순서를 나의 변덕에 의해 바꾼다고 해보자.
@Getter
@AllArgsConstructor
public static class Member2 {
private String team; //name <-> team 순서 변경
private String name;
private int age;
}
이런 경우 우리는 생성자의 인자 순서 또한 (name,team,age) 로 바꿔지길 원하진 않을 거다. 만약 그렇다면 위 생성자를 작성한 모든 코드의 파라미터 순서를 바꿔줘야하기 때문이다.
롬복은 시키지 않아도 생성자의 파라미터 순서 또한 바꿔버린다.
class CoreApplicationTests {
@Getter
public static class Member1 {
private String team;
private String name;
private int age;
public Member1(String name, String team, int age) {
this.name = name;
this.team = team;
this.age = age;
}
}
@Getter
@AllArgsConstructor
public static class Member2 {
private String team;
private String name;
private int age;
}
@Test
void test() {
Member1 member1 = new Member1("11st","CX",27);
Member2 member2 = new Member2("11st","CX",27);
assertThat(member1.getTeam()).isEqualTo("CX"); // 통과
assertThat(member2.getTeam()).isEqualTo("CX"); // 실패!
}
}
아래 테스트는 실패한다. 우리는 member2의 Team 이 "CX"이기를 기대하지만, 롬복에 의해 parameter순서가 뒤바뀌고, 이름과 팀은 타입 또한 문자열로 같기때문에 아무런 문제도 컴파일러는 눈치채지 못한다.