2016-08-17 2 views
2

최대 절전 모드 5.1.0.Final, Guice, Jersey를 사용합니다. dabatase에서 최신 데이터를 쿼리하는 영속 컨텍스트와 힘을 취소Hibernate - ThreadLocal <EntityManager> v 작업 당 EntityManager

public class HibernateModule extends AbstractModule { 

    private static final ThreadLocal<EntityManager> ENTITY_MANAGER_CACHE = new ThreadLocal<EntityManager>(); 

    @Provides @Singleton 
    public EntityManagerFactory provideEntityManagerFactory(@Named("hibernate.connection.url") String url, 
     @Named("hibernate.connection.username") String userName, 
     @Named("hibernate.connection.password") String password, 
     @Named("hibernate.hbm2ddl.auto") String hbm2ddlAuto, 
     @Named("hibernate.show_sql") String showSql) { 

     Map<String, String> properties = new HashMap<String, String>(); 
     properties.put("hibernate.connection.driver_class", "org.postgresql.Driver"); 
     properties.put("hibernate.connection.url", url); 
     properties.put("hibernate.connection.username", userName); 
     properties.put("hibernate.connection.password", password); 
     properties.put("hibernate.connection.pool_size", "1"); 
     properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect"); 
     properties.put("hibernate.hbm2ddl.auto", hbm2ddlAuto); 
     properties.put("hibernate.show_sql", showSql); 
     properties.put("hibernate.cache.use.query_cache", "false"); 
     properties.put("hibernate.cache.use_second_level_cache", "false"); 

     return Persistence.createEntityManagerFactory("db-manager", properties); 
    } 

    @Provides 
    public EntityManager provideEntityManager(EntityManagerFactory entityManagerFactory) { 

     EntityManager entityManager = ENTITY_MANAGER_CACHE.get(); 

     if (entityManager == null || !entityManager.isOpen()) 
      ENTITY_MANAGER_CACHE.set(entityManager = entityManagerFactory.createEntityManager()); 

     entityManager.clear(); 

     return entityManager; 
    } 
} 

entityManager.clear()를 사용 : 나는 EntityManagerFactory를 만들고 EntityManager 인스턴스를 관리 HibernateModule 있습니다. GenericDAO은 HibernateModule로부터 주입 된 EntityManager을 수신한다. 주요 방법 :

public class GenericDAOImpl<T> implements GenericDAO<T> { 

    @Inject 
    protected EntityManager entityManager; 

    private Class<T> type; 

    public GenericDAOImpl(){} 

    public GenericDAOImpl(Class<T> type) { 
     this.type = type; 
    } 

    @Override 
    public void save(T entity) { 
     entityManager.getTransaction().begin(); 
     entityManager.persist(entity); 
     entityManager.getTransaction().commit(); 
    } 

    @Override 
    public T find(Long entityId) { 
     return (T) entityManager.find(type, entityId); 
    } 
} 

은 이전에 내가 구현에 모든 DB 작업에 새로운 EntityManager을 제공하는 솔루션을 시도했지만 그것은 "지속에 전달 분리 된 실체"와 같은 부작용을 초래할.

EntityManagerThreadLocal<EntityManager>에서 재사용하는 것이 좋습니까? 이 구현의 잠재적 인 단점이 있습니까?

답변

2

올바르게 작동해야합니다. 스프링 프레임 워크는 EntityManagerThreadLocal 클래스를 사용합니다. 참조에서 :

봄 만들고 현재 쓰레드에 세션을 바인딩하기 쉽게 만들어 투명하게

당신이 EntityManager의 인스턴스를 다시 사용하려는 경우가 JPA 힌트, PersistenceContextTypeFlushModeType에 대해 기억해야한다 .

관련 문제