✅ Transient 어노테이션
Spring에서
@Transient
주석은 엔터티 클래스의 필드를 임시로 표시하는 데 사용된다. 즉, 해당 필드가 데이터베이스에 지속되어서는 안되는 경우 사용한다. 이 주석은 Java 코드에 포함하고 싶지만 데이터베이스에 저장하고 싶지 않은 필드가 엔터티 클래스에 있는 경우 특히 유용하다.✅ 정의와 적용 예시
그렇다면,
@Transient
의 작동 방식과 이를 언제 사용할 수 있는지 알아보자- 정의: 필드를
@Transient
로 표시하면 Spring이 엔터티 저장, 업데이트 또는 쿼리와 같은 데이터베이스 작업을 수행할 때 해당 필드를 무시한다. 이는 Hibernate와 같은 지속성 공급자에게 SQL 작업에 이 필드를 포함하지 말라고 지시하는 것이다!
- 적용 예시:
- 임시로 계산된 필드: 때로는 다른 지속형 필드를 기반으로 계산된 필드가 있다. 이 필드는 임시적으로 사용하는 필드이므로 데이터베이스에 저장할 필요가 없는 경우가 있다.
- 비영구적 정보: 애플리케이션 내 내부 처리에 필요하지만 데이터베이스 저장과 관련이 없는 필드는 임시로 표시될 수 있다.
- 보안 관련 정보: 비밀번호나 임시 토큰과 같이 유지하고 싶지 않은 민감한 정보가 포함된 필드는 임시로 표시될 수 있다.
✅ 사용 예시
id
, username
, password
라는 세 가지 필드가 있는 User
엔터티 클래스가 있다고 가정해보자. 또한 사용자 인증 중에 생성되지만 데이터베이스에 유지되어서는 안 되는 temporaryToken
이라는 필드를 포함하고 있다.@Transient
주석을 사용하여 User
엔터티 클래스를 정의하는 방법은 다음과 같습니다.import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Transient; import lombok.Data; import lombok.NoArgsConstructor; import lombok.AllArgsConstructor; @Entity @Data @AllArgsConstructor @NoArgsConstructor public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private String password; @Transient private String temporaryToken; }
temporaryToken
필드를 @Transient
로 표시했다. 이는 이 필드가 데이터베이스에 유지되어서는 안 된다는 것을 Spring에 알려준다.이제 Spring 저장소 또는 EntityManager를 사용하여
User
엔터티를 저장하거나 업데이트하면 temporaryToken
필드가 무시되고 해당 값이 데이터베이스에 저장되지 않는다.다음은 Spring Boot 애플리케이션에서 이 엔터티를 사용하는 방법에 대한 예입니다.
javaCopy code import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoApplication implements CommandLineRunner { @Autowired private UserRepository userRepository; // Assuming UserRepository is your JPA repository interface public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Override public void run(String... args) throws Exception { // Creating a new user User user = new User("john.doe", "password123"); user.setTemporaryToken("temporaryToken123"); // Saving the user userRepository.save(user); // Retrieving the user from the database User retrievedUser = userRepository.findById(user.getId()).orElse(null); if (retrievedUser != null) { // Print user details (temporaryToken won't be persisted) System.out.println("Retrieved User:"); System.out.println("ID: " + retrievedUser.getId()); System.out.println("Username: " + retrievedUser.getUsername()); System.out.println("Password: " + retrievedUser.getPassword()); System.out.println("Temporary Token: " + retrievedUser.getTemporaryToken()); // null을 리턴할 것이다!! } } }
이 예에서는
User
객체를 저장하기 전에 temporaryToken
값을 설정하더라도 @Transient
주석으로 인해 데이터베이스에는 저장되지 않는다. 데이터베이스에서 사용자를 꺼내, 사용자 정보를 출력하면
temporaryToken
필드가 null을 출력할 것이다. null은 데이터베이스에 저장되지 않았음을 나타낸다.✅ 주의사항
@Transient
어노테이션을 사용하면 특정 필드를 지속성에서 제외하는 데 유용하게 사용할 수 있지만, 과도하게 사용하면 시스템 디자인에 문제가 발생할 수 있다.
- 스키마 생성 중에는 임시 필드가 고려되지 않는다. 자동 스키마 생성을 사용하는 경우 임시 필드가 데이터베이스 스키마에 반영되지 않는다는 점을 기억해야 한다.
✅ 대체 방안
- 특정 속성을 DB 지속성에서 제외하려면 해당 속성이 없는 DTO(Data Transfer Object)를 새로 만드는 것이 좋다.
- 필드가 유지되는 방식을 맞춤설정해야 하는 경우
insertable
및updatable
과 같은 속성이 포함된 JPA의@Column
주석을 사용하는 것이 좋다.
Share article