many를 insert할 때 update query가 추가적으로 발생한다.
entity를 관리하는 외래키가 다른 table(many)에 존재한다.
부모 Entity에서 자식 Entity로 메세지를 보내는 객체 관계일 때
미리 저장 안했을 때 ❌
@Test
void name() {
Student student = new Student();
Book book1 = new Book();
Book book2 = new Book();
student.books = Arrays.asList(book1,book2);
studentRepository.save(student);
}
Exception 발생 : save the transient instance before flushing
미리 저장했을 때 ⭕
@Test
void name() {
Student student = new Student();
Book book1 = bookRepository.save(new Book());
Book book2 = bookRepository.save(new Book());
student.books = Arrays.asList(book1,book2);
studentRepository.save(student);
}
(참고) 여기에 트랜잭션이 붙으면 정상작동한다. 왜 그럴까.
@Transactional
@Test
void name() {
Many many1 = new Many();
Many many2 = new Many();
Many many3 = new Many();
One one = new One();
one.add(many1);
one.add(many2);
one.add(many3);
One save = oneRepository.save(one);
}
👎 불필요한 Table 추가적으로 사용
class Stundet {
...
@OneToMany
public List<Book> books = new ArrayList<>();
Hibernate:
insert
into
book
(id, name)
values
(null, ?)
Hibernate:
insert
into
book
(id, name)
values
(null, ?)
Hibernate:
insert
into
student
(id, name)
values
(null, ?)
Hibernate:
insert
into
student_books
(student_id, books_id)
values
(?, ?)
Hibernate:
insert
into
student_books
(student_id, books_id)
values
(?, ?)
many(book)에 column id를 update 해준다.
class Stundet {
...
@OneToMany
@JoinColumn(name="book_id")
public List<Book> books = new ArrayList<>();
Hibernate:
insert
into
book
(id, name)
values
(null, ?)
Hibernate:
insert
into
book
(id, name)
values
(null, ?)
Hibernate:
insert
into
student
(id, name)
values
(null, ?)
Hibernate:
update
book
set
book_id=?
where
id=?
Hibernate:
update
book
set
book_id=?
where
id=?
연관관계를 끊고 Many를 지워야 한다.
@Transactional
public void practice(Student student) {
List<Book> books = student.books;
bookRepository.delete(books.get(0));
}
constraint ["FKMGR4X6DGXPDKWAF421Q0F7ETK: PUBLIC.STUDENT_BOOKS FOREIGN KEY(BOOKS_ID) REFERENCES PUBLIC.BOOK(ID) (1)"; SQL statement:
// Student가 Book 2권 가지고 있는 상태
@Transactional
public void practice() {
Student student = studentRepository.findById(1L).get();
student.removeBookById(1L);
}
Hibernate:
delete
from
student_books
where
student_id=?
Hibernate:
insert
into
student_books
(student_id, books_id)
values
(?, ?)
@Transactional
public void practice() {
bookRepository.deleteById(1L);
}
Hibernate:
delete
from
book
where
id=?
Many를 삭제하는 게 아니라 연관관계를 끊는다고 생각하면 연관관계를 null로 update한다.