개발강의정리/Spring

[스프링 데이터 JPA] 4-12. 스프링 데이터 JPA: Auditing

nineDeveloper 2019. 12. 14.
728x90

스프링 데이터 JPA

4. 스프링 데이터 JPA 활용

포스팅 참조 정보

GitHub

공부한 내용은 GitHub에 공부용 Organizations에 정리 하고 있습니다

해당 포스팅에 대한 내용의 GitHub 주소

실습 내용이나 자세한 소스코드는 GitHub에 있습니다
포스팅 내용은 간략하게 추린 핵심 내용만 포스팅되어 있습니다

https://github.com/freespringlecture/spring-data-jpa-study/tree/chap04-12-jpa-auditing

해당 포스팅 참고 인프런 강의

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%8D%B0%EC%9D%B4%ED%84%B0-jpa/dashboard

실습 환경

  • Java Version: Java 11
  • SpringBoot Version: 2.1.2.RELEASE

12. 스프링 데이터 JPA: Auditing

엔티티의 변경 시점에 언제, 누가 변경했는지에 대한 정보를 기록하는 기능

스프링 데이터 JPA의 Auditing 실습

Account 클래스 생성

Auditing 기록을 남기기 위한 사용자 정보 클래스

@Entity
public class Account {

    @Id @GeneratedValue
    private Long id;
    private String username;
    private String password;
}

Comment 클래스에 Auditing 정보를 남기기위한 항목 추가

@CreatedDate
private Date created;

@LastModifiedDate
private Date updated;

@CreatedBy
@ManyToOne
private Account createdBy;

@LastModifiedBy
@ManyToOne
private Account updatedBy;

Auditing 를 사용할 클래스 상단에 @EntityListeners 설정

@Entity
@EntityListeners(AuditingEntityListener.class)
public class Comment {

AccountAuditAware 클래스 생성

유저정보를 꺼내올 수 있는 기능

@Service
public class AccountAuditAware implements AuditorAware<Account> {
    @Override
    public Optional<Account> getCurrentAuditor() {
        System.out.println("looking for current user");
        return Optional.empty();
    }
}

@EnableJpaAuditing

  • Auditing는 자동설정 되지 않으므로 아래와 같이 수동으로 설정
  • AccountAuditAware 도 빈 이름으로 설정(클래스이름은 안됨)
@SpringBootApplication
@EnableJpaAuditing(auditorAwareRef = "accountAuditAware")

테스트 로직

accountAuditAware 빈도 사용해야 하므로 @SpringBootTest 로 테스트

@RunWith(SpringRunner.class)
@SpringBootTest
public class CommentRepositoryTest {

    @Autowired
    CommentRepository comments;

    @Autowired
    PostRepository posts;

    @Test
    public void getComment() {
        Post post = new Post();
        post.setTitle("jpa");
        Post savedPost = posts.save(post);

        Comment comment = new Comment();
        comment.setComment("spring data jpa projection");
        comment.setPost(savedPost);
        comment.setUp(10);
        comment.setDown(1);
        comments.save(comment);

        comments.findByPost_Id(savedPost.getId(), CommentOnly.class).forEach(c -> {
            System.out.println("========================");
//            System.out.println(c.getVotes());
            System.out.println(c.getComment());
        });
    }
}

 

아쉽지만 이 기능은 스프링 부트가 자동 설정 해주지 않습니다

  1. 메인 애플리케이션 위에 @EnableJpaAuditing 추가
  2. 엔티티 클래스 위에 @EntityListeners(AuditingEntityListener.class) 추가
  3. AuditorAware 구현체 만들기
  4. @EnableJpaAuditingAuditorAware 빈 이름 설정하기

스프링 시큐리티에서 유저정보를 가져와서 넣을 수 있는 방법

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#auditing

class SpringSecurityAuditorAware implements AuditorAware<User> {

  public Optional<User> getCurrentAuditor() {

    return Optional.ofNullable(SecurityContextHolder.getContext())
              .map(SecurityContext::getAuthentication)
              .filter(Authentication::isAuthenticated)
              .map(Authentication::getPrincipal)
              .map(User.class::cast);
  }
}

 

JPA의 라이프 사이클 이벤트

http://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#events-jpa-callbacks

https://docs.jboss.org/hibernate/orm/4.0/hem/en-US/html/listeners.html

Hibernate가 제공하는 기능 어떠한 Entity에 변화가 일어났을때 특정한 콜백을 실행할 수 있는 이벤트를 발생시켜 줌
콜백을 Entity에 정의할 수 있음
이 이벤트를 이용해서 Audit 기능을 구현할 수도 있음

  • @PrePersist: Entity가 저장이 되기 전에 호출
  • @PreUpdate
  • @PreRemove

예제

@Entity
public class Comment {
    @PrePersist
    public void prePersist() {
        System.out.println("Pre Persist is called");
    }
}


728x90

댓글

💲 추천 글