처음에 상속관계로 접근하려고 했었는데, 상속관계로 맺으려면 아래와 같은 문제가 생긴다.
https://www.inflearn.com/questions/85190
(김영한 강사님께 질문)
일단 상태 중 일부를 잘라보면, 위와 같이 database를 설계했습니다.
(그림 - 위 db 사진 참조)
Artist가 User의 상태 전부를 갖고 있으므로 Artist가 User를 상속받게 Entity 설계를 했습니다.
그런데 이와 같이 설계를 하면 Artist는 독립적인 Id가 없습니다. 그래서 artist_id에 직접적으로 접근할 수가 없어서 두가지 문제가 발생합니다.
첫번째로 아티스트를 생성하려면 직접적으로 접근해서 생성하지 못하고, 유저 정보가 생성될 때만 생성할 수 있습니다. 그래서 artist를 생성할 때 현재 다음과 같이 생성되게 로직을 짰습니다.
만약 7번 유저가 이미 등록돼있고, 7번 유저에 대해서 artist 등록을 한다고 가정해보겠습니다. 그러면 아래와 같은 로직을 따라갑니다.
7번 유저를 가져옴 -> builder를 통해서 artist를 생성. 그러면 8번 유저가 생성되고 8번 유저가 artist와 연결됨 -> 7번 유저는 삭제
그런데 위와 같이 로직을 따르는게 최적화에 있어서 좋지 못하다는 생각이 듭니다. 또한 7번 유저 인덱스가 비어서 빈 인덱스가 생겼기 때문에 데이터를 볼때도 좋지 않을 것 같다는 생각이 듭니다.
두번째로 artist_id가 없기 때문에 artist와 다른 테이블을 mapping 시킬 때 까다로운 부분이 있습니다. 그래서 artist_id를 따로 만들어야 하나 생각이 들다가도 로직상으로 맞지 않는 것 같기도 합니다.
대충 Artist에 id값이 없어서 까다롭다는 이야기
해당 유저를 아티스트로 바꾸는게 나중에 일어난다면 유저와 아티스트를 명확하게 분리해야 합니다.
상속보다 위임을 사용해야 한다. 상속은 현업에서 거의 사용되지 않는다.
위임은 한 클래스가 다른 클래스를 멤버변수로 갖는 것. 즉 @OneToOne을 하라는 이야기. 여기서 주의할 것은 DB랑 OOP 사이에서 헷갈려 하지말고,두 개를 따로 봐야한다. 여기서 위임이란 자바단에서 이야기 하는 것.
artist에는 user_id가 없기 때문에 오류가 생긴다.
이렇게 하니까 됐는데, 다시 아티스트 저장하는 코드에서 오류가 생겼다.
해결 : user를 저장안해서 생긴 문제였다.
Stackoverflow 1
종속 테이블에 cascade = CascadeType.ALL 을 달아주니까 해결됐다.
Every bidirectional association has two sides : the owner side, and the inverse side. The inverse side is the one which has the mappedBy attribute. The owner side is the other one. JPA/Hibernate only cares about the owner side. So if you just initialize the inverse side, the association won't be persisted.
https://stackoverflow.com/questions/16380008/persist-onetoone-relation-with-springdata-jpa
초기화의 문제인 것 같다.
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Accessors(chain = true)
@Entity
public class Artist{
@Id
@Column(name = "artist_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@MapsId
@OneToOne(fetch = FetchType.LAZY,cascade = CascadeType.ALL)
@JoinColumn(name = "artist_id", referencedColumnName="user_id")
private User user;
private String img;
}
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@Entity
public class User {
@Id
@Column(name = "user_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
private String password;
private String nickname;
private Integer money;
}
(스승이 써보라고 한것)
@PrimaryKeyJoinColumn
@OneToOne(mappedBy = "user")
@JsonManagedReference
private Artist artist;