티스토리 뷰

반응형

토이 프로젝트로 관리자 페이지를 만들게 되었습니다.

관리자 페이지에서 작업을 하게 되면 중요한 부분이 'History' 라고 생각합니다. 누가 언제 만들었고, 누가 언제 수정했는지... 이러한 작업을 소스에서 반복적으로 입력해 주는 것이 아니라, 알아서 입력될 수 있도록 JPA Audit을 사용해봤습니다. 작업을 완료한지는 꽤 되었지만... 게을러서 지금 포스팅을 하게 되었습니다. 더 늦게 올리면 잊어 버릴까봐.

개발환경은 SpringBoot (2.x.x)+ Maven + spring-boot-starter-data-jpa + spring-boot-starter-security 입니다.

Spring Security 환경에서만 생성자와 수정자 입력이 가능하다는 점 꼭 기억하고 작업 부탁 드립니다.

 

먼저 Config 클래스를 만들고, AuditorAware Interface의 구현체를 return 할 수 있도록 bean을 선언합니다.

@Configuration
@EnableJpaAuditing
public class JpaAuditConfig {

    @Bean
    public AuditorAware<AdminUser> auditorProvider() {
        return new AuditorAwareImpl(); // AuditorAware 의 구현체 객체 생성
    }
}

 

AuditorAware를 구현한 클래스 입니다.

스프링 시큐리티의 SecurityContextHolder에서 사용자 정보를 가지고 오도록 합니다.

이부분을 구현하기 전에, Spring Security에서 UserDetails를 구현하여 사용자를 관리하는 클래스를 구현해야 겠네요.

포스팅 순서가 잘못된 거 같긴한데... Spring Security를 사용하여 사용자를 관리하는 부분은 다음에 기회가 되면 올리도록 하겠습니다. 저 같은 경우는 AdminUser Entity와 UserDetails를 구현한 AdminUserDetails를 통해 이미 만들어 놨습니다.

public class AuditorAwareImpl implements AuditorAware<AdminUser> {

    public Optional<AdminUser> getCurrentAuditor() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(null == authentication || !authentication.isAuthenticated()){
            return null;
        }

        return Optional.of(((AdminUserDetails)authentication.getPrincipal()).getAdminUser());
    }
}

 

그리고 JPA Audit을 이용하여, 공통으로 사용할 칼럼들을 추상클래스로 선언해줍니다.

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class CommonAudit {

    @LastModifiedBy
    @ManyToOne
    @JoinColumn(name="MOD_ADMIN", referencedColumnName = "ADMIN_ID")
    private AdminUser modifyBy;

    @CreatedBy
    @ManyToOne
    @JoinColumn(name="REG_ADMIN",referencedColumnName = "ADMIN_ID", updatable = false)
    private AdminUser createdBy;

    @LastModifiedDate
    @Column(name="MOD_DATE")
    private LocalDateTime modifiedDate;

    @CreatedDate
    @Column(name="REG_DATE", updatable = false)
    private LocalDateTime createdDate;

    @Column(name = "DELETE")
    private boolean delete;
}

- @EntityListeners : Entity를 DB에 적용하기 전 또는 후, 콜백을 요청할 수 있는 어노테이션.

   AuditingEntityListener.class에 선언되어있는 기능들을 통해 History를 관리할 수 있다.

- @MappedSuperclass : 부모 클래스에서 자식 클래스에게 매핑 정보가 제공할 때 사용하는 어노테이션 이다.

   Entity는 Entity만 상속받을 수 있기에, 공통으로 가지고 있는 Entity가 아닌 클래스를 상속 받을 때 사용한다. 

 

- @LastModifiedBy : 누가 마지막에 수정하였는지

 

- @CreateBy : 누가 생성 하였는지

 

- @LastModifiedDate : 마지막 수정한 날

 

- @CreateDate : 생성한 날

@JoinColumn(name="MOD_ADMIN", referencedColumnName = "ADMIN_ID")

   : Admin Entity의 ADMIN_ID를 join 하여 수정자의 ID를 가지고 온다는 의미 입니다.

 

실제 상속받는 클래스에서는 이렇게 사용하면 됩니다.

public class Member extends  CommonAudit implements Serializable {
    private static final long serialVersionUID = -1899422181748243449L;

    @Id @GeneratedValue
    @Column(name = "MEMBER_SEQ",updatable = false)
    private Long memberSeq;
    
    
   ................................

참고 

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

 

Spring Data JPA - Reference Documentation

Example 103. Using @Transactional at query methods @Transactional(readOnly = true) public interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") v

docs.spring.io

https://stackoverflow.com/questions/49023607/spring-data-2-0-x-auditoraware-getcurrentuser-method-throws-abstractmethoderror

 

Spring Data 2.0.x AuditorAware getCurrentUser method throws AbstractMethodError

I am trying to implement AuditorAware into my web application. Below is the list of my library version: jsf 2.2.13 hibername 5.1.3.Final spring 5.0.3.RELEASE spring-data 2.0.3.RELEASE spring-secur...

stackoverflow.com

 

https://eclipse4j.tistory.com/201

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함