@Test
@Transactional
@DisplayName("[createVoteResult] 중복 투표가 아닌데 중복 투표하면 실패")
public void transactionSaveTestSuccess(){
Restaurant restaurant1 = Restaurant.builder().name("abc").restaurantHash("13").build();
Restaurant restaurant2 = Restaurant.builder().name("def").restaurantHash("12").build();
this.restaurantRepository.save(restaurant1);
this.restaurantRepository.save(restaurant2);
// 레스토랑 엔티티를 만든 후 저장
Vote vote = Vote.builder()
.title("Test")
.email(null)
.allowDuplicateVote(false)
.expireAt(LocalDateTime.now().plusHours(2))
.voteHash("abcdef")
.build();
Voter voter = Voter.builder().nickname("abcd").profileImage(1).vote(vote).build();
this.voterRepository.save(voter);
this.voteRepository.save(vote);
List<Voter> voters = vote.getVoters();
System.out.println("voters = " + voters);
}
@Test
// @Transactional
@DisplayName("[createVoteResult] 중복 투표가 아닌데 중복 투표하면 실패")
public void transactionSaveTestFail(){
Restaurant restaurant1 = Restaurant.builder().name("abc").restaurantHash("13").build();
Restaurant restaurant2 = Restaurant.builder().name("def").restaurantHash("12").build();
this.restaurantRepository.save(restaurant1);
this.restaurantRepository.save(restaurant2);
// 레스토랑 엔티티를 만든 후 저장
Vote vote = Vote.builder()
.title("Test")
.email(null)
.allowDuplicateVote(false)
.expireAt(LocalDateTime.now().plusHours(2))
.voteHash("abcdef")
.build();
Voter voter = Voter.builder().nickname("abcd").profileImage(1).vote(vote).build();
this.voterRepository.save(voter);
this.voteRepository.save(vote);
List<Voter> voters = vote.getVoters();
System.out.println("voters = " + voters);
}
org.hibernate.TransientPropertyValueException:
object references an unsaved transient instance - save the transient instance before flushing : capstone.restaurant.entity.Voter.vote -> capstone.restaurant.entity.Vote
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:368)
object references an unsaved transient instance - save the transient instance before flushing
기본적으로 영속성 컨텍스트는 commit 혹은 flush 가 될때 , 쓰기 지연 sql 저장소의 쿼리들을 DB 에 반영한다. 즉 매번 persist , save 등의 동작을 하더라도 즉시 DB 에 반영되는 것이 아니라 쓰기 지연 SQL 저장소 에 쌓여 있다가 flush 나 commit 이 될때, DB 에 쿼리를 날린다.
첫번째 코드는 영속성 컨텍스트가 테스트 코드 전체 범위이다.
this.voterRepository.save(voter);
this.voteRepository.save(vote);

@Test
@Transactional
@DisplayName("[createVoteResult] 중복 투표가 아닌데 중복 투표하면 실패")
public void duplicateVoteFailTest1(){
Restaurant restaurant1 = Restaurant.builder().name("abc").restaurantHash("13").build();
Restaurant restaurant2 = Restaurant.builder().name("def").restaurantHash("12").build();
this.restaurantRepository.save(restaurant1);
this.restaurantRepository.save(restaurant2);
Vote vote = Vote.builder()
.title("Test")
.email(null)
.allowDuplicateVote(false)
.expireAt(LocalDateTime.now().plusHours(2))
.voteHash("abcdef")
.build();
Voter voter = Voter.builder().nickname("abcd").profileImage(1).vote(vote).build();
this.voteRepository.save(vote);
this.voterRepository.save(voter);
entityManager.flush();
entityManager.clear();
Vote vote1 = this.voteRepository.findByVoteHash(vote.getVoteHash());
for (Voter vote1Voter : vote1.getVoters()) {
System.out.println("vote1Voter.getNickname() = " + vote1Voter.getNickname());
}
}