@Test
void findByDate() {
Member member = Member.createMember("a", "a", "aa", "male", "aamoof@gmail.com");
//em.persist(member);
TodoList todoList = TodoList.createTodoList(member, LocalDate.now());
//em.persist(todoList);
TodoListItem todoListItem1 = TodoListItem.creatTodoListItem("hello", todoList, LocalDate.now(),0);
TodoListItem todoListItem2 = TodoListItem.creatTodoListItem("hello", todoList, LocalDate.now(),0);
List<TodoListItem> listItems = new ArrayList<>();
listItems.add(todoListItem1);
listItems.add(todoListItem2);
todoListItemRepository.save(todoListItem1);
todoListItemRepository.save(todoListItem2);
List<TodoListItem> findList = todoListItemRepository.findByDate(LocalDate.now());
Assertions.assertThat(findList).isEqualTo(listItems);
}
(위와 같은 경우 meber와 todolist를 저장한 후에 flusing하라고 오류가 난다.)
결론부터 얘기하자면 save the transient instance before flushing 뜨는 이유는 간단하다. 데이터의 참조 무결성을 지키기 위해서다.
우리가 하는 Test는 Transactional 어노테이션이 붙은 테스트 -> 즉 트랜잭션을 확인 하기위한 테스트이다.
(트랜잭션은 데이터베이스 관리 시스템 또는 유사한 시스템에서 상호작용의 단위이다.)
예를 들어 TablePerson엔티티와 TableGender엔티티가 있다고 생각하자. 우리는 TablePerson과 TableGender를 N:1관계로 설정 했다.
@Entity
TablePerson{
.
.
.
@ManyToOne
@joinColumn(name="GengerID")
private TableGender tableGender;
}
(DB에 아무런 데이터도 저장되어있지 않는 상태)
실패하는 테스트:
TableGender tableGender = new TableGender(1,"Male");
TablePerson tablePerson1 = new TablePerson(1,Rumman1,rumman1@mail.com,tableGender);
TablePerson tablePerson2 = new TablePerson(2,Rumman2,rumman2@mail.com,tableGender);
em.persist(tablePerson1)
em.persist(tablePerson2)
이유: save the transient instance before flushing 이 뜨면서 실패 했을 것이다.
왜냐하면 tableGender를 서버에 저장 안 해줬기 때문이다.
우리는 엔티티를 정의할때 TablePerson과 TableGender를 분명 N:1로 명시해주었다.
하지만 tableGender를 em.perist(tableGender)를 해주지 않는다면
DB에서는 tablePerson1과 tablePerson2만 남게된다. 이 점이 문제라는거다.
우리는 분명 N:1이라고 했다.
그렇다면 tablePerson1의 외래키와 tablePerson2의 외래키인 tableGender가 반드시 존재해야한다는 것이다.
그래야 N:1의 관계가 성립된다.
즉 em.persist(tableGender)를 저장해주지 않는 다는 것은 N:1 관계를 어기는 행위이다.