오늘의 포스팅은 필드를 어떻게 하면 효율적으로 작성할 수 있는가에 대한 글입니다. 개발을 하다보면 반복되는 코드들을 메서드로 묶거나 인터페이스를 통해 구현하여 객체지향적인 코드를 구성하려고 Java 세계에서는 특히 더 노력하는 추세입니다.
이것은 필드에서도 이어집니다. 보통 ERD 를 만들고 보다 보면 각 테이블에 createAt, updateAt(modifiedAt) 등이 공통 속성으로 들어가는 걸 쉽게 볼 수 있습니다. 이럴 때 마다 모든 객체에 같은 필드를 추가하기에는 보기가 좋지 않기에 이럴 때 BaseEntity 사용하여 반복되는 코드를 줄일 수 있습니다.
JPA 를 활용하려하는 간단한 예제를 통하여 코드로 살펴보겠습니다.
먼저 앞서 말한 두 필드가 담긴 BaseEntity 만들어 줍니다.

@MappedSuperclass : JPA에서 이 클래스를 상속하는 다른 엔티티들만 매핑되고 테이블에 매핑되지 않는다는 의미입니다. 즉, BaseEntity는 데이터베이스 테이블에 해당하지 않고, 상속받는 클래스들이 테이블에 매핑됩니다.
@EntityListeners(AuditingEntityListener.class): AuditingEntityListener를 통해 JPA의 Auditing 기능을 활성화시킵니다. 이 기능은 엔티티의 생성 및 수정 시간을 자동으로 관리해줍니다. 이 코드에서 createAt, modifiedAt 필드에 값이 자동으로 채워지게 됩니다.
@CreatedDate: 이 애너테이션은 해당 필드에 엔티티가 처음 생성될 때의 날짜와 시간을 자동으로 할당해줍니다. 여기서는 createAt 필드에 생성 일시가 저장됩니다.
@LastModifiedDate: 이 애너테이션은 해당 필드에 엔티티가 마지막으로 수정된 날짜와 시간을 자동으로 할당해줍니다. 여기서는 modifiedAt 필드에 마지막 수정 일시가 저장됩니다.

@Entity: 이 클래스는 JPA 엔티티로 매핑됩니다. 즉, Customer 클래스는 데이터베이스 테이블과 매핑됩니다.
@Getter: BaseEntity와 마찬가지로 Lombok 애너테이션으로 Customer 클래스의 모든 필드에 대해 getter 메서드를 생성합니다.
@Builder: 이 애너테이션을 통해 빌더 패턴을 사용할 수 있게 됩니다. 이로써 Customer 객체를 생성할 때 직관적이고 가독성 높은 방법으로 객체를 생성할 수 있습니다.
@NoArgsConstructor: 기본 생성자를 자동으로 생성합니다. JPA 엔티티에서는 기본 생성자가 필요합니다.
@AllArgsConstructor: 모든 필드를 파라미터로 받는 생성자를 자동으로 생성합니다.
@AuditOverride(forClass = BaseEntity.class): BaseEntity에서 제공하는 생성일자와 수정일자 필드를 Customer 클래스에 포함시킬 때, BaseEntity의 Auditing 기능을 오버라이드하여 Customer 클래스에서 적용할 수 있게 합니다.
@Id: 이 필드는 JPA 엔티티의 기본 키를 지정하는 애너테이션입니다. Customer 엔티티에서는 id 필드가 기본 키로 설정됩니다.
@GeneratedValue(strategy = GenerationType.IDENTITY): id 필드는 데이터베이스에서 자동으로 생성되는 값이며, 기본 키로 설정된 필드에 대한 값을 자동으로 증가시키는 전략을 지정합니다. 여기서는 IDENTITY 전략을 사용해 DB에서 자동 증가하는 값을 사용합니다.
@Column(name = "id", nullable = false): id 필드를 데이터베이스의 "id" 컬럼에 매핑합니다. 이 컬럼은 nullable = false로 설정되어 null 값을 허용하지 않음을 의미합니다.

JPA Auditing 기능을 사용하려면, application 클래스에 @EnableJpaAuditing을 붙여주어야 사용이 가능합니다.
AuditingEntityListener 클래스는 엔티티의 생성, 수정, 삭제 등의 이벤트가 발생하였을 때, 이와 같은 엔티티의 변경 사항을 Audit(감사)하기 위한 클래스입니다. 해당 어노테이션으로 리스너 클래스를 등록하여, 엔티티에 대한 이벤트가 발생하였을 때, 이벤트에 대한 처리를 진행할 수 있습니다.
따라서, @CreateDate와 @LastModifiedDate를 적용하여, 엔티티의 생성일과 마지막 수정일을 간편하게 관리할 수 있습니다.
@EnableJpaRepositories란?
JPA Repository 빈을 활성화하는 어노테이션입니다.
별도로 basePackages 속성을 주지 않으면 @SpringBootApplication에 설정한 빈 scan 범위와 동일한 범위로 빈을 scan 합니다.