account 등록 후 citizen을 등록하려고 보니 관련된 테이블들이 너무 많습니다.
JPA에 익숙하지 않아서 조금 낯선 상황입니다. 🥲
@Entity
public class AccountEntity {
@Id
@GeneratedValue(strategy = jakarta.persistence.GenerationType.IDENTITY)
private Long accountId;
private String email;
private String password;
@Enumerated(EnumType.STRING)
private AccountEmailVerificationStatus emailVerificationStatus;
@Enumerated(EnumType.STRING)
private AccountActiveStatus activeStatus;
@OneToMany(mappedBy = "accountEntity")
private List<CitizenEntity> citizens = new ArrayList<>();
private String emailVerificationToken;
public AccountEntity() {}
public AccountEntity(String email, String password, AccountEmailVerificationStatus emailVerificationStatus, AccountActiveStatus activeStatus) {
this.email = email;
this.password = password;
this.emailVerificationStatus = emailVerificationStatus;
this.activeStatus = activeStatus;
}
public AccountEntity(Account account) {
this.email = account.email();
this.password = account.password();
this.emailVerificationStatus = account.emailVerificationStatus();
this.activeStatus = account.activeStatus();
emailVerificationToken = account.emailVerificationToken();
}
public Account toDomain() {
return new Account(this.accountId ,this.email, this.password, this.emailVerificationToken, this.emailVerificationStatus, this.activeStatus);
}
public void update(AccountUpdateRequest updateRequest) {
this.email = updateRequest.email();
}
public void update(Account account) {
this.email = account.email();
this.password = account.password();
this.emailVerificationStatus = account.emailVerificationStatus();
this.activeStatus = account.activeStatus();
emailVerificationToken = account.emailVerificationToken();
}
public void delete() {
this.activeStatus = AccountActiveStatus.DELETED;
}
}
@Entity
public class CitizenEntity {
@Id
@GeneratedValue(strategy = jakarta.persistence.GenerationType.IDENTITY)
private Long citizenId;
private String nickname;
private String phoneNumber;
private LocalDate createdAt;
private CitizenActiveStatus activeStatus;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="account_id")
private AccountEntity accountEntity;
@OneToMany(mappedBy = "addressEntity", cascade = CascadeType.ALL)
private List<AddressEntity> addressEntity;
@OneToOne(mappedBy = "hobbyEntity", cascade = CascadeType.ALL)
private HobbyEntity hobbyEntity;
public CitizenEntity(Citizen citizen) {
this.nickname = citizen.nickname();
this.createdAt = citizen.createdAt();
this.phoneNumber = citizen.phoneNumber();
this.activeStatus = CitizenActiveStatus.ACTIVE;
}
public CitizenEntity() {}
public Citizen toDomain() {
return null;
}
public void delete() {
this.activeStatus = CitizenActiveStatus.DELETED;
}
}
@Entity
public class AddressEntity {
@Id
@GeneratedValue(strategy = jakarta.persistence.GenerationType.IDENTITY)
private Long addressId;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "citizen_id")
private CitizenEntity citizen;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "si_do_id")
private SiDoEntity siDo;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "si_gun_gu_id")
private SiGunGuEntity siGunGu;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "eup_myeon_dong_id")
private EupMyeonDongEntity eupMyeonDong;
}
@Entity
public class HobbyEntity {
@Id
private Long id;
private String hobby;
private LocalDate createdAt;
}
@ManyToOne
, Account에는 mappedBy
CitizenHobbyEntity
의 목적은 관계 테이블의 이용이므로 따로 repository를 만들었습니다.@Entity
public class CitizenEntity {
@Id
@GeneratedValue(strategy = jakarta.persistence.GenerationType.IDENTITY)
private Long citizenId;
private String nickname;
private String phoneNumber;
private LocalDate createdAt;
private CitizenActiveStatus activeStatus;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="account_id")
private AccountEntity accountEntity;
@OneToMany(mappedBy = "addressEntity", cascade = CascadeType.ALL)
private List<AddressEntity> addressEntity;
@OneToMany(mappedBy = "hobbyEntity", cascade = CascadeType.ALL)
private List<HobbyEntity> hobbyEntity;
public CitizenEntity(Citizen citizen) {
this.nickname = citizen.nickname();
this.createdAt = citizen.createdAt();
this.phoneNumber = citizen.phoneNumber();
this.activeStatus = CitizenActiveStatus.ACTIVE;
}
public CitizenEntity() {}
public Citizen toDomain() {
return null;
}
public void delete() {
this.activeStatus = CitizenActiveStatus.DELETED;
}
}
@Getter
@Entity
@IdClass(CitizenHobbyId.class)
public class CitizenHobbyEntity {
@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "citizenId")
private CitizenEntity citizen;
@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "hobbyId")
private HobbyEntity hobby;
}
public class CitizenHobbyId implements Serializable {
private Long citizenId;
private Long hobbyId;
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
@Override
public int hashCode() {
return super.hashCode();
}
}
@Entity
public class HobbyEntity {
@Id
private Long hobbyId;
private String hobby;
private LocalDate createdAt;
}
예시) 1154510100 : 서울특별시 금천구 가산동
시도는 무조건 전체 조회
시군구 조회
읍면동 조회
@Repository
@RequiredArgsConstructor
public class AddressDao implements AddressRepository {
private final AddressJpaRepository addressJpaRepository;
private final SiDoJpaRepository siDoJpaRepository;
private final SiGunGuJpaRepository siGunGuJpaRepository;
private final EupMyeonDongJpaRepository eupMyeonDongJpaRepository;
@Override
public AddressResponse save(Address address) {
AddressEntity addressEntity = addressJpaRepository.save();
return addressEntity.toDomain();
return null;
}
@Override
public List<SiDo> getSiDoList() {
List<SiDoEntity> all = siDoJpaRepository.findAll();
return all.stream().map(SiDoEntity::toDomain).collect(Collectors.toList());
}
@Override
public List<SiGunGu> getSiGunGuList(String sido) {
List<SiGunGuEntity> all = siGunGuJpaRepository.findBySido(sido);
return all.stream().map(SiGunGuEntity::toDomain).collect(Collectors.toList()));
}
@Override
public List<EupMyeonDong> getEupMyeonDongList(String sido, String sigungu) {
List<EupMyeonDongEntity> all = eupMyeonDongJpaRepository.findBySidoAndSigungu(sido, sigungu);
return all.stream().map(EupMyeonDongEntity::toDomain).collect(Collectors.toList());
}
}
위와 같이 만들고 보니 시군구에선 시도 코드를, 읍면동에선 시도, 시군구 코드를 가지고 있는게 조회시 편할 것 같다는 생각이 들었습니다.
이걸 JPA로 어떻게 풀어야 하는지가 고민입니다.
참고