본문으로 건너뛰기

Annotation

애노테이션

@Repository

  • 스프링 빈으로 등록, JPA 예외를 스프링 기반 예외로 예외 변환

@PersistenceContext

  • 엔티티 메니저( EntityManager ) 주입

예시

@Repository
public class MemberRepository {
@PersistenceContext
private EntityManager em;

public void save(Member member) {
em.persist(member);
}
}

@PersistenceUnit

  • 엔티티 메니터 팩토리( EntityManagerFactory ) 주입

@Transactional

  • org.springframework.transaction.annotation.Transactional
  • JPA의 모든 변경은 트랜잭션 안에서 동작
  • 트랜잭션, 영속성 컨텍스트
    • 데이터의 변경은 트랜잭션 안에서 이뤄져야 한다
  • @Transactional(readOnly = true)
    • 데이터의 변경이 없는 읽기 전용 메서드에 사용한다
    • 영속성 컨텍스트를 플러시 하지 않으므로 약간의 성능 향상

예시

  • 모든 메소드에 @Transactional(readOnly = true) 적용
  • 데아터 변경이 필요한 메소드 join()에서 @Transactional 적용
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class MemberService {
private final MemberRepository memberRepository;

@Transactional
public Long join(Member member) {
memberRepository.save(member);
return member.getId();
}

public List<Member> findMembers() {
return memberRepository.findAll();
}

public Member findOne(Long memberId) {
return memberRepository.findOne(memberId);
}
}

테스트 코드 작성

  • @Transactional을 테스트에 사용하면 반복 가능한 테스트 지원한다
    • 각각의 테스트를 실행할 때마다 트랜잭션을 시작하고 테스트가 끝나면 트랜잭션을 강제로 롤백
    • 아래의 회원가입() 메소드에서 실제 INSER SQL이 DB에 전달되지 않는다
    • 즉 DB에는 반영되지 않는다
@SpringBootTest
@Transactional
public class MemberServiceTest {
@Autowired
MemberService memberService;

@Autowired
MemberRepository memberRepository;

@Test
public void 회원가입() throws Exception {
//Given
Member member = new Member();
member.setName("kim");

//When
Long saveId = memberService.join(member);

//Then
assertEquals(member, memberRepository.findOne(saveId));
}
}

@PrePersist

  • 이벤트 어노테이션
  • 엔티티를 영속화하기 전에 호출된다.
@PrePersist
public void prePersist() {
LocalDateTime now = LocalDateTime.now();
createdDate = now;
updatedDate = now;
}

@PreUpdate

  • 이벤트 어노테이션
  • 엔티티를 업데이트하기 전에 호출된다.
@PreUpdate
public void preUpdate() {
updatedDate = LocalDateTime.now();
}