두가지 방법으로 사용할 수 있다
1. 생성자에서 주입하는 방법
2. spring bean으로 등록해두고 바로 주입받는 방법
@Repository
public class MemberJpaRepository {
private final EntityManager em;
private final JPAQueryFactory jpaQueryFactory;
public MemberJpaRepository(EntityManager em) {
this.em = em;
this.jpaQueryFactory = new JPAQueryFactory(em);
}
}
@SpringBootApplication
public class QuerydslPracticeApplication {
public static void main(String[] args) {
SpringApplication.run(QuerydslPracticeApplication.class, args);
}
@Bean
JPAQueryFactory jpaQueryFactory(EntityManager em) {
return new JPAQueryFactory(em);
}
}
: 해당 방법은 두번 주입 받아야 하기 때문에 테스트 코드를 짤 때 어려움
@Repository
public class MemberJpaRepository {
private final EntityManager em;
private final JPAQueryFactory jpaQueryFactory;
public MemberJpaRepository(EntityManager em, JPAQueryFactory jpaQueryFactory) {
this.em = em;
this.jpaQueryFactory = jpaQueryFactory;
}
}
📌 빈에 등록해서 사용하는 경우 lombok
@RequiredArgsConstructor
를 사용할 수 있다
@Repository
@RequiredArgsConstructor
public class MemberJpaRepository {
private final EntityManager em;
private final JPAQueryFactory jpaQueryFactory;
}
JPAQueryfactory를 bean에 등록했을 때 싱글톤으로 생성된다
같은 객체를 모든 멀티 스레드에서 다 쓰면 문제가 생기지 않을까?
동시성 문제가 발생하지 않나?
-> 문제가 없음
JPAQueryfactory는 EntityManager에 의존한다
EntityManager를 Spring에서 쓸 때 동시성문제에 관계없이 트랜젝션으로 따로따로 분리되어 움직인다.
프록시 가짜를 주입하여 트랜젝션 단위로 라우팅 해줌
참고: 동시성 문제는 걱정하지 않아도 된다. 왜냐하면 여기서 스프링이 주입해주는 엔티티 매니저는 실제 동작 시점에 진짜 엔티티 매니저를 찾아주는 프록시용 가짜 엔티티 매니저이다. 이 가짜 엔티티 매니저는 실제 사용 시점에 트랜잭션 단위로 실제 엔티티 매니저(영속성 컨텍스트)를 할당해준다.
더 자세한 내용은 자바 ORM 표준 JPA 책 13.1 트랜잭션 범위의 영속성 컨텍스트를 참고하자.