Development Tip

EntityManager Vs.

yourdevel 2020. 11. 8. 11:21
반응형

EntityManager Vs. EntityManagerFactory


긴 질문입니다. 참아주세요.

우리는 웹 애플리케이션에 Spring + JPA를 사용하고 있습니다. 우리 팀은 주입을 통해 토론한다 EntityManagerFactoryGenericDAO(AppFuse에 의해 제공되는 라인의 제네릭 뭔가를 기반으로 DAO, 우리는 사용하지 않는 JpaDaosupport주입을 통해 어떤 이유로) EntityManager. 우리는 "애플리케이션 관리 지속성"을 사용하고 있습니다.

주입에 대한 EntityManagerFactory주장은 너무 무거워서 필요하지 않다는 EntityManager것입니다. 또한 Spring은 모든 웹 요청에 대해 DAO의 새 인스턴스를 생성하므로 동일한 EntityManager인스턴스 에서 두 스레드가 공유 하므로 동시성 문제가 발생하지 않을 것 입니다.

EFM 주입에 대한 주장은 공장을 다루는 것이 항상 좋은 방법이라는 것입니다.

어떤 방법이 가장 좋은지 잘 모르겠습니다. 누군가 나를 계몽 해 주시겠습니까?


EntityManagerFactory 대 EntityManager 주입의 장단점은 모두 여기 Spring 문서 에 설명되어 있으며 개선 할 수 있는지 확실하지 않습니다.

즉, 귀하의 질문에 해결해야 할 몇 가지 사항이 있습니다.

... Spring은 모든 웹 요청에 대해 DAO의 새 인스턴스를 생성합니다.

이것은 올바르지 않습니다. DAO가 Spring Bean이면 scopeBean 정의 속성을 통해 달리 구성하지 않는 한 싱글 톤 입니다. 모든 요청에 ​​대해 DAO를 인스턴스화하는 것은 미친 짓입니다.

EMF 주입에 대한 주장은 공장을 다루는 것이 항상 좋은 방법이라는 것입니다.

이 주장은 실제로 물을 담고 있지 않습니다. 일반적인 모범 사례는 작업을 수행하는 데 필요한 최소한의 협력자와 함께 객체를 주입해야한다고 말합니다.


드디어 모은 것을 내려 놓고 있습니다. Spring Reference의 " Implementing DAOs based on plain JPA " 섹션에서 발췌 :

EntityManagerFactory 인스턴스는 스레드로부터 안전하지만 EntityManager 인스턴스는 그렇지 않습니다. 삽입 된 JPA EntityManager는 JPA 사양에 정의 된대로 애플리케이션 서버의 JNDI 환경에서 가져온 EntityManager처럼 작동합니다. 현재 트랜잭션 EntityManager (있는 경우)에 모든 호출을 위임합니다. 그렇지 않으면 작업 당 새로 생성 된 EntityManager로 폴백되어 사실상 스레드로부터 안전하게 사용됩니다.

즉, JPA 사양에 따라 EntityManager 인스턴스는 스레드로부터 안전하지 않지만 Spring이 처리하면 스레드로부터 안전합니다.

Spring을 사용하는 경우 EntityManagerFactory 대신 EntityManager를 삽입하는 것이 좋습니다.


나는 이것이 이미 잘 다루어 졌다고 생각하지만 단지 몇 가지 요점을 강화하기 위해서입니다.

  • DAO Spring에 의해 주입 된 경우 기본적으로 싱글 톤 입니다. 매번 새 인스턴스를 만들려면 범위를 프로토 타입으로 명시 적으로 설정해야합니다.

  • @PersistenceContext 의해 주입 된 엔티티 관리자 는 스레드로부터 안전 합니다.

즉, 다중 스레드 응용 프로그램에서 단일 DAO에 대해 몇 가지 문제가있었습니다. 결국 DAO를 인스턴스 빈으로 만들었고 문제가 해결되었습니다. 따라서 문서에 한 가지가 언급되어 있지만 응용 프로그램을 철저히 테스트하고 싶을 것입니다.

후속 조치 :

내 문제의 일부는 내가 사용하고 있다고 생각합니다.

@PersistenceContext(unitName = "unit",
    type = PersistenceContextType.EXTENDED)

PersistenceContextType.EXTENDED를 사용하는 경우 올바르게 이해 한 경우 트랜잭션을 수동으로 닫아야합니다. 자세한 내용은 스레드를 참조하십시오.

또 다른 후속 조치 :

인스턴스 DAO를 사용하는 것은 매우 나쁜 생각입니다. DAO의 각 인스턴스에는 자체 지속성 캐시가 있으며 하나의 캐시에 대한 변경 사항은 다른 DAO 빈에서 인식되지 않습니다. 나쁜 충고에 대해 죄송합니다.


DAO에 @Repository Spring 어노테이션을 설정하고 EntityManager를 Spring에서 관리하고 @PersistenceContext 어노테이션으로 주입하는 것이 모든 것을 유창하게 작동시키는 가장 편리한 방법이라는 것을 알았습니다. 공유 된 EntityManager 및 예외 변환의 스레드 안전성을 활용할 수 있습니다. 기본적으로 공유 EntityManager는 예를 들어 관리자에서 여러 DAO를 결합하는 경우 트랜잭션을 관리합니다. 결국 DAO가 빈혈이 될 것임을 알게 될 것입니다.

참고 URL : https://stackoverflow.com/questions/1310087/injecting-entitymanager-vs-entitymanagerfactory

반응형