spring bootでデータアクセスにspring-boot-starter-data-jpa(実装的にはHibernateが使われている)を使っている時、
クラステーブル継承の実現の仕方を理解するのに時間がかかったのでメモ。
[クラステーブル継承]については過去postの中で記載している
参考)
Hibernate Inheritance Mapping | Baeldung
※one to one の関連で実現しようと頑張ってたがやり方を間違っていた。普通に継承すればよかった模様。
※下記サンプルコードは個人的都合でEntityではなくMapperという命名を使っている。
データ構成
スーパータイプとしてuserテーブルがあって、サブタイプとしてindividual_user(個人ユーザー)がある。
※ここには記載してないが、サブタイプとして他にcorporate_user(企業ユーザー)があったりする想定
usersテーブル(スーパータイプ)
id |
created_at |
updated_at |
1 |
2021-11-11 |
2021-11-11 |
individual_usersテーブル(サブタイプ)
users.idとindividual_users.user_idがリファレンスキーとなっている。
Entityコード
UserMapper.java
import lombok.Data;
import javax.persistence.*;
import java.time.ZonedDateTime;
@Data
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "users")
public class UserMapper {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private ZonedDateTime createdAt;
private ZonedDateTime updatedAt;
IndividualUserMapper.java
import lombok.Data;
import javax.persistence.*;
import java.time.ZonedDateTime;
@Data
@Entity
@PrimaryKeyJoinColumn(name = "userId")
@Table(name = "individual_users")
public class IndividualUserMapper extends UserMapper {
private String name;
}
Repositoryコード
import org.springframework.data.jpa.repository.JpaRepository;
public interface IndividualUserInfraRepository extends JpaRepository<IndividualUserMapper, Long> {
使う側
var userMapper = new IndividualUserMapper();
userMapper.setName("yamada");
userMapper.setCreatedAt(ZonedDateTime.now());
userMapper.setUpdatedAt(ZonedDateTime.now());
var savedIndividualUser = individualUserInnerRepository.save(userMapper);
var loadedIndividualUser = individualUserInnerRepository.findById(savedIndividualUser.getId());