User
엔티티에 List<String>
타입의 hashtags
객체를 만드려고 함@Entity
@Getter
public class User {
@Id @GeneratedValue
@Column(name = "user_id")
private Long id;
private List<String> hashtags = new ArrayList<>();
}
Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.List, at table: User({테이블명}), for columns: [org.hibernate.mapping.Column({칼럼명})]
@Entity
@Getter
public class User {
@Id @GeneratedValue
@Column(name = "user_id")
private Long id;
@ElementCollection
@CollectionTable(name = "Hashtags", joinColumns = @JoinColumn(name = "user_id"))
@Column(name = "hashtag") // 컬럼명 지정
private List<String> hashtags = new ArrayList<>();
}
String
을 이용해 "hashtag1, hashtag2, …" 이런 식으로 저장하면 안되나🤔? 했지만,값 타입 컬렉션 사용시 제약 사항 (관련 포스팅)
- 값 타입은 엔티티와 다르게 식별자 개념이 없다.
- 값은 변경하면 추적이 어렵다.
- 값 타입 컬렉션에 변경 사항이 발생하면, 주인 엔티티와 연관된 모든 데이터를 삭제하고, 값 타입 컬렉션에 있는 현재 값을 모두 다시 저장해야 한다.
- 값 타입 컬렉션을 매핑하는 테이블은 모든 컬럼을 묶어서 기본키를 구성해야 함: null 입력X, 중복 저장X (현재 상황에서는, ‘user_id+hashtag’가 기본키)
user_id
로 삭제하는 로직을 구현하기 위해, 추적을 쉽게 할 필요성을 느낌UserHashtag
와 User
: 다대일 양방향 매핑 사용User
엔티티에서 영속성 전이, 고아 객체 제거 사용해, 라이프사이클을 같게 함@Entity
@Getter
public class User {
@Id @GeneratedValue
@Column(name = "user_id")
private Long id;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<UserHashtag> userHashtags = new ArrayList<>();
}
@Entity
@Getter
public class UserHashtag {
@Id @GeneratedValue
@Column(name = "user_hashtag_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user; // FK
private String hashtag;
}