[실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발] 01. 프로젝트 환경설정

Turtle·2024년 7월 3일
0
post-thumbnail

🙄JPA와 DB 설정, 동작확인

✔️테스트용 회원 리포지토리

@Repository
public class MemberRepository {

	@PersistenceContext
	EntityManager em;

	public Long save(Member member) {
		em.persist(member);
		return member.getId();
	}

	public Member find(Long memberId) {
		Member member = em.find(Member.class, memberId);
		return member;
	}
}
  • ✔️@PersistenceContext
    • EntityManager를 빈으로 주입할 때 사용하는 어노테이션
    • 스프링에서는 영속성 관리를 위해서 EntityManager가 존재한다.
    • 스프링 컨테이너가 시작될 때 EntityManager를 만들어서 빈으로 등록해둔다.
  • ✔️@PersistenceContext 사용하는 이유
    • EntityManagerFactoryEntityManager를 만들어서 제공해주는데 이 때, EntityManager는 절대 공유해선 안 된다.
    • 스프링 컨테이너는 기본적으로 싱글톤으로 동작한다. 공유에 주의해야 한다.
    • 그러나 @PersistenceContext으로 EntityManager를 주입받아도 동시성 문제가 발생하지 않는다.

✔️회원 리포지토리 테스트 코드

@RunWith(SpringRunner.class)
@SpringBootTest
class MemberRepositoryTest {

	@Autowired
	public MemberRepository memberRepository;

	@DisplayName("회원 리포지토리 테스트 코드")
	@Test
	void save() throws Exception {
		// given
		Member member = new Member();
		member.setName("테스트 회원");

		// when
		Long savedId = memberRepository.save(member);
		Member findMember = memberRepository.find(savedId);

		// then
		Assertions.assertThat(findMember.getId()).isEqualTo(member.getId());
	}
}

실행 결과

No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call
  • ✔️오류 원인 분석
    • 엔티티 매니저를 통한 데이터 변경은 항상 트랜잭션 내에서 일어나야 한다.
    • @Transactional 어노테이션을 걸어준다.
    • 테스트 코드 메서드에 @Transactional 어노테이션을 붙여주면 테스트가 수행되고 난 후 롤백이 이루어진다.

0개의 댓글