의문
다른 프레임워크를 하며 의문점이 생겼다. 다른 프레임워크들은 직접 쿼리문을 쓰거나 ORM 등을 이용하여 쿼리를 작성하여 객체의 필드값을 하나하나 빼서 저장을 하는 경우가 있는데, Spring 에서 아니, JPA/Hibernate 에서는 @Getter 등이 없어도 repository.save(entity) 만 하면 값이 저장이 된다. 어떻게 이게 가능한 걸까?
@Getter 없이 어떻게 값을 읽고 전부 저장할까?
Hibernate 는 기본적으로 엔티티의 상태를 읽고 쓸 때 Java 의 리플렉션 기능을 이용한다. 예를 들어 Entity 클래스 필드에 @Id 같은 어노테이션이 붙어 있으면, Hibernate 는 해당 필드에 직접 접근 하여 값을 읽고 쓴다.
이러한 방법이 있기에 Getter, Setter 등이 없어도 값을 읽는 것이 가능하다.
엔티티: 이거 사생활 침해 아니냐..
Shut up.
지금부터 엔티티의 사생활을 침해하는 방법을 알아보자.
Field field = entity.getClass().getDeclaredField(propertyName);
field.setAccessible(true);
Object value = field.get(entity);
꺄악 엔티티의 사생활을 침해했다.
저 getDeclaredField 가 뭘까
getDeclaredField(propertyName)
이건 자바의 리플렉션 API 중 하나다.
클래스 내부에 선언된 특정 필드를 이름으로 가져오는 메서드다.
Class<?> clazz = Product.class;
Field field = clazz.getDeclaredField("name");
이렇게 하면 Product 클래스에 선언된 name 이라는 필드를 가져온다.
private, protected, public 상관 없이 전부 가져 올 수 있다.
캡슐화 박살내는 메서드. 평소에는 잘 쓰지 않을 것이다.
여기서 setAccessible(true) 를 하면 private 필드도 접근이 가능해진다.
field.setAccessible(true); // private 필드 접근 가능하게 설정
Object value = field.get(product); // 값 읽기
field.set(product, "맥북"); // 값 쓰기
그랬던 것이었다.
오랜만에 자바 코드치니까 즐겁다.
'CS' 카테고리의 다른 글
RAG란 무엇일까? (0) | 2025.02.01 |
---|---|
Service 끼리 의존 하는 것에 대하여 (0) | 2025.01.14 |
@Transactional 은 어떻게 작동할까요? (0) | 2024.12.24 |