객체의 입장에서 공통 매핑정보가 필요할 때 사용한다.
공통 매핑 정보가 필요할 때 ,부모 클래스에 선언을 해주고 속성만 상속 받아서 사용하고 싶을 때 @MappedSuperClass 를 사용한다. 상속광계 매핑이 아니다.
@MappedSuperclass가 선언되어 있는 클래스는 엔티티가 아니다. 당연히 테이블과 매핑도 안된다. 단순히 부모 클래스를 상속 받는 자식 클래스에 매핑 정보만 제공한다.
조회, 검색이 불가하다. 부모 타입으로 조회하는 것이 불가능하다는 이야기.(em.find(BaseEntity) 불가능)
직접 생성해서 사용할 일이 없으므로 추상 클래스로 만드는 것을 권장한다.
테이블과 관계가 없고, 단순히 엔티티가 공통으로 사용하는 매핑 정보를 모으는 역할을 한다.
주로 등록일, 수정일, 등록자, 수정자 같은 전체 엔티티에서 공통으로 적용하는 정보를 모을 때 사용한다.
@PrePersist
:JPA 엔티티(Entity)가 비영속(new/transient) 상태에서 영속(managed) 상태가 되는 시점 이전에 실행되는 어노테이션
@PreUpdate
:영속 상태의 엔티티를 이용하여 데이터 업데이트를 수행하기 이전에 실행되는 어노테이션
다음은 순수 JPA를 사용해서 공통 매핑정보의 컬럼들을 @MapperSuperClass를 사용한 클래스의 코드이다.
@MappedSuperclass
@Getter
public class JpaBaseEntity {
@Column(updatable = false)
private LocalDateTime createdDate;
private LocalDateTime updatedDate;
@PrePersist
public void prePersist() {
LocalDateTime now = LocalDateTime.now();
createdDate = now;
updatedDate = now;
}
@PreUpdate
public void preUpdate() {
updatedDate = LocalDateTime.now();
}
}
밑의 Member엔티티는 @MappedSuperclass의 클래스인 BaseEntity를 상속 받는다
@Entity public class Member extends BaseEntity { ... }
해당 SQL을 보면 member 엔티티를 create할 때 BaseEntity의 컬럼들 마저 생성된것을 볼 수 있다.
Hibernate:
create table Member (
id bigint generated by default as identity,
createdBy varchar(255),
createdDate timestamp,
lastModifiedBy varchar(255),
lastModifiedDate timestamp,
age integer,
name varchar(255),
team_id bigint,
primary key (id)
)
@EnableJpaAuditing
@SpringBootApplication
public class GunshopApplication {
public static void main(String[] args) {
SpringApplication.run(GunshopApplication.class, args);
}
}
이렇게 스프링부트 Main메서드가 있는 클래스에 @EnableJpaAuditing를 붙여주자
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass @Getter
public class BaseEntity {
@CreatedDate
@Column(updatable = false) // 생성시간은 update되면 안됨
private LocalDateTime createDate;
@LastModifiedDate
private LocalDateTime lastModifiedDate;
}
다음 아래의 코드는 BaseEntity를 상속받은 Member엔티티이다.
@Entity
@Getter @Setter @AllArgsConstructor
public class Member extends BaseEntity{
/**
* 회원은 여러 상품을 주문할 수 있다
*/
@Id
@GeneratedValue
@Column(name = "member_id")
private Long id;
private String loginId;
private String password;
private String name;
@Embedded
private Address address;
@OneToMany(mappedBy = "member")
private List<Order> orders = new ArrayList<>();
이제 어플리케이션을 실햏해보면
Member엔티티에 해당 컬럼을 직접 안써주어도 테이블을 Create할때 해당 컬럼이 생성되는것을 볼 수 있다. 쿼리문과 테이블 🔽