오답노트
[Spring JPA] Entity Relations 본문
1:1 관계
Book 과 BookReviewInfo 의 1:1 관계를 나타내는 예시이다.
연결할 두 Entity에 상대방 멤버 변수를 만들고 OneToOne Annotation을 달아주면 연결된다.
OneToOne Annotation에 mappedBy를 설정하게 되면 ToString이 순환 참조로 인해 에러가 발생한다.
둘 다 사용하고 싶다면 한쪽에는 @ToString.Exclude를 사용하자.
OneToOne
@Entity
@NoArgsConstructor
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Book extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String category;
private Long authorId;
private Long publisherId;
@OneToOne
private BookReviewInfo bookReviewInfo;
}
@Entity
@NoArgsConstructor
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class BookReviewInfo extends BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) // 현재 테이블에 hibernate_sequence 생성
private Long id;
//private Long bookId;
private float avgReviewScore;
private int reviewCount;
@OneToOne(optional = false)
private Book book;
}
OneToOne(mappedBy)
@Entity
@NoArgsConstructor
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Book extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String category;
private Long authorId;
private Long publisherId;
@OneToOne(mappedBy = "book")
@ToString.Exclude
private BookReviewInfo bookReviewInfo;
}
1:N 관계
OneToMany Annotation을 사용하여 관계를 형성한다.
해당 Entity의 JoinColumn을 사용하여 매핑 테이블이 생성되는 것을 방지 할 수 있다.
@NoArgsConstructor
@AllArgsConstructor
@RequiredArgsConstructor
@Data
@Builder
@Entity
@EntityListeners(value = {UserEntityListener.class})
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class User extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NonNull
private String name;
@NonNull
private String email;
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id", insertable = false, updatable = false)
private List<UserHistory> userHistories = new ArrayList<>();
}
@Entity
@NoArgsConstructor
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class UserHistory extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "user_id")
private Long userId;
private String name;
private String email;
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
}
N:1 관계
ManyToOne으로 관계를 형성한다.
cascade 옵션은 영속성 정의라는 개념인데, Entity를 영속화 할 때, 연관된 Entity도 영속화 한다.
저장할 때만 사용하려면 cascade = CascadeType.PERSIST 로 설정해주면 되며,
전체 적용인 CascadeType.ALL 로 설정한다.
@Entity
@NoArgsConstructor
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Review extends BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String title;
private String content;
private float score;
@ManyToOne(cascade = CascadeType.ALL)
private User user;
@ManyToOne(cascade = CascadeType.ALL)
private Book book;
}
N:N 관계
ManyToMany로 관계를 형성한다.
서로 여러 개의 entity를 가지게 되므로 List 멤버 변수를 갖게 된다.
@Entity
@NoArgsConstructor
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Author extends BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String country;
@ManyToMany
@ToString.Exclude
private List<Book> books = new ArrayList<>();
}
@Entity
@NoArgsConstructor
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Book extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String category;
private Long authorId;
@ManyToMany
@ToString.Exclude
private List<Author> authors = new ArrayList<>();
}
중간 테이블을 이용한 N:N 관계
N:N의 관계를 1:N 관계의 테이블을 만들어 N:N처럼 사용할 수 도 있다.
@Entity
@NoArgsConstructor
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Book extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String category;
private Long authorId;
// @ManyToMany
@OneToMany
@JoinColumn(name = "book_id")
@ToString.Exclude
private List<BookAndAuthor> bookAndAuthors = new ArrayList<>();
}
@Entity
@NoArgsConstructor
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Author extends BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String country;
//@ManyToMany
@OneToMany
@JoinColumn(name = "author_id")
@ToString.Exclude
private List<BookAndAuthor> bookAndAuthors = new ArrayList<>();
}
아래는 Book과 Author 클래스를 모두 가지고 있는 BookAndAuthor 클래스를 만들었다.
Book과 Author 클래스를 이어주는 클래스로 이 클래스로 인해 Book과 Author 클래스는 N:N관계를 간접적으로 형성하게 된다.
@Entity
@NoArgsConstructor
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class BookAndAuthor extends BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
private Book book;
@ManyToOne
private Author author;
}
'Java > Spring' 카테고리의 다른 글
[Spring Security] SessionManagementFilter (0) | 2023.07.27 |
---|---|
[Spring JPA] 영속성 전이(Cascade) 와 고아제거속성(orphanRemoval) (0) | 2023.07.24 |
[Spring JPA] Query Method (0) | 2023.07.19 |
[Spring JPA] Auditing (0) | 2023.07.19 |
[Spring JPA] H2 In-Memory DB (0) | 2023.07.18 |