[Spring] JPA Auditing 기능 추가해 createdDate, lastModifiedDate 자동 생성하기

김진성·2021년 12월 11일
1

Spring

목록 보기
5/10

이번 주제는 JPA Auditing 기능을 Rest API에 추가하는 것이다. 사실 우리가 데이터베이스를 업데이트 하거나 사용하다보면 사실 데이터 내용이 수정되는 경우가 생긴다. 물론, 최초 생성 과정에서도 보통 createdAt으로 저장하는 경우가 있다. Django에서는 auto_now_add=True를 이용하는데 Spring에서는 어떤 방식을 사용하는지 알아보도록 하겠다.

Spring Rest API Auditing

0. 기본 세팅

[Spring] JPA 와 AWS 연동하기 저번에 생성해놓은 AWS 과정을 따라하면서 세팅하면 된다.

추가적인 유효성 검사 세팅

implementation 'org.springframework.boot:spring-boot-starter-validation'

1. Model에 결합가능한 Auditable 생성하기

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@Getter
@Setter
public abstract class Auditable<U> {
    
    @CreatedBy
    protected U createdBy;

    @CreatedDate
    @Temporal(TemporalType.TIMESTAMP)
    protected Date createdDate;

    @LastModifiedBy
    protected U lastModifiedBy;

    @LastModifiedDate
    @Temporal(TemporalType.TIMESTAMP)
    protected Date lastModifiedDate;

}

여기를 보게 되면 Auditable 객체가 생겨났는데 다른 모델에다가 추가하게 되면 그 모델들은 이제 생성, 수정 과정에서 누가, 언제 했는지에 대한 정보를 저장할 수 있게 된다.

2. User 모델 생성

@Entity
@Table(name="user")
@EntityListeners(AuditingEntityListener.class)
@Getter
@Setter
public class User extends Auditable<String> {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column(name = "first_name", nullable = false)
    private String firstName;

    @Column(name = "last_name", nullable = false)
    private String lastName;

    @Column(name = "email_address", nullable = false)
    private String emailId;
}

3. UserRepository 생성

@Repository
public interface UserRepository extends JpaRepository <User, Long>{
    
}

4. UserController 생성

@RestController
@RequestMapping("/api/v1")
public class UserController {
    
    @Autowired
    private UserRepository userRepository;

    @GetMapping("/users")
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }

    @GetMapping("/users/{id}")
    public ResponseEntity<User> getUserById(
        @PathVariable(value = "id") Long userId
    ) throws ResourceNotFoundException {
        User user = userRepository.findById(userId)
                        .orElseThrow(() -> new ResourceNotFoundException("User not found : " + userId));
        return ResponseEntity.ok().body(user);
    }

    @PostMapping("/users")
    public User createUser(@Valid @RequestBody User user) {
        return userRepository.save(user);
    }

    @PutMapping("/users/{id}")
    public ResponseEntity<User> updateUser(
      @PathVariable(value = "id") Long userId,
      @Valid @RequestBody User userDetails) throws ResourceNotFoundException {
        User user = userRepository.findById(userId)
          .orElseThrow(() -> new ResourceNotFoundException("User not found :: " + userId));
  
        user.setEmailId(userDetails.getEmailId());
        user.setLastName(userDetails.getLastName());
        user.setFirstName(userDetails.getFirstName());
        user.setLastModifiedDate(new Date());
        final User updatedUser = userRepository.save(user);
        return ResponseEntity.ok(updatedUser);
    }

    @DeleteMapping("/users/{id}")
    public Map<String, Boolean> deleteUser(
         @PathVariable(value = "id") Long userId) throws ResourceNotFoundException {
         User user = userRepository.findById(userId)
          .orElseThrow(() -> new ResourceNotFoundException("User not found :: " + userId));

        userRepository.delete(user);
         Map<String, Boolean> response = new HashMap<>();
         response.put("deleted", Boolean.TRUE);
         return response;
    }

}

5. AuditorAwareImpl 생성하기

public class AuditorAwareImpl implements AuditorAware<String> {
    
    @Override
    public Optional<String> getCurrentAuditor() {
        return Optional.of("exist");
    }

}

6. Home 수정하기

@SpringBootApplication
@EnableJpaRepositories(basePackageClasses = UserRepository.class)
@EnableJpaAuditing(auditorAwareRef = "auditorAware")
public class SpringJpaAuditingApplication {


	@Bean
	public AuditorAware<String> auditorAware() {
		return new AuditorAwareImpl();
	}

	public static void main(String[] args) {
		SpringApplication.run(SpringJpaAuditingApplication.class, args);
	}

}

여기서 @EnableJpaAuditing(auditorAwareRef = "auditorAware") 를 설정하지 않으면 아래 테스트 결과에서 볼 수 있듯이 null값이 나오기 때문에 설정해줘야 한다.

7. 최종 테스트하기

POST

아래의 생성 시간과 누가 수정했는지 저장할 수 있다. 나는 일단 createdBy, lastModifiedBy는 "exist"로 설정하였다.

GET

처음에는 설정을 잘 못해서 null 값이 출력되었지만 수정 후 잘 나올 수 있게 되었다.

최종 코드 spring-jpa-auditing에서 확인할 수 있습니다.

profile
https://medium.com/@jinsung1048 미디엄으로 이전하였습니다.

0개의 댓글