-
JPA AuditingBE/스프링 2024. 11. 14. 17:35
JPA Auditing이란?
엔티티의 생성, 수정과 관련된 메타 데이터를 자동으로 관리하기 위한 기능
예를 들어, 엔티티가 생성된 시각, 마지막으로 수정된 시각, 생성한 사용자, 수정한 사용자 등의 정보를 데이터베이스에 자동으로 기록- 데이터가 변경되는 시점 감지
- 데이터 변경 시 자동으로 이력 기록 (created_at, created_by...)
- 엔티티 클래스에 어노테이션 추가하여 사용
1. Gradle에 의존성 추가
dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' }
2. Spring Boot 애플리케이션 @EnableJpaAuditing 추가
@SpringBootApplication @EnableJpaAuditing public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } }
또는 별도의 설정 클래스를 생성
@Configuration @EnableJpaAuditing public class JpaAuditingConfig { }
3. Base Entity 생성
@Getter @MappedSuperclass @EntityListeners(AuditingEntityListener.class) public abstract class BaseEntity { @CreatedDate private LocalDateTime createdAt; @LastModifiedDate private LocalDateTime updatedAt; @CreatedBy private String createdBy; @LastModifiedBy private String updatedBy; }
4. AuditorAware 구현
: @CreatedBy와 @LastModifiedBy를 사용하려면 현재 사용자를 반환하는 AuditorAware 구현체를 생성
AuditorAware<T>는 JPA Auditing 기능에서 현재 감사 주체(Auditor)를 제공하기 위한 인터페이스
Spring Security 연동 : 인증된 사용자 이름 반환
@Component("auditorProvider") public class SecurityAuditorAware implements AuditorAware<String> { @Override public Optional<String> getCurrentAuditor() { // Spring Security에서 현재 인증 정보 가져오기 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); // 인증 정보가 없거나 인증되지 않은 경우 if (authentication == null || !authentication.isAuthenticated()) { return Optional.empty(); } // 인증된 사용자의 이름 반환 return Optional.of(authentication.getName()); } }
추가 정보(예: 이메일, 사용자 ID)를 반환하려면,
Custom Principal 사용
Spring Security에서 사용자 정보를 UserDetails 구현체로 커스터마이징한 경우, Principal 객체에서 정보를 가져올 수 있음
@Override public Optional<String> getCurrentAuditor() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication == null || !authentication.isAuthenticated()) { return Optional.empty(); } Object principal = authentication.getPrincipal(); if (principal instanceof CustomUserDetails) { CustomUserDetails userDetails = (CustomUserDetails) principal; return Optional.of(userDetails.getEmail()); // 사용자 이메일 반환 } return Optional.empty(); // Principal이 CustomUserDetails가 아닌 경우 }
Custom Principal은 Spring Security의 Authentication 객체에 사용자 정의 정보 포함 가능
-> 인증 프로세스에서 Principal로 사용자 객체(UserDetails 구현체 등)를 설정하는 방식
5. 엔티티에서 BaseEntity를 상속받아 Auditing 필드 포함
@Getter @NoArgsConstructor @Entity public class User extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; public User(String name, String email) { this.name = name; this.email = email; } }
'BE > 스프링' 카테고리의 다른 글
QueryDSL + Projection (1) 2024.11.13 JPA : Entity 연관 관계 / @JoinColumn (1) 2024.11.04