【问题标题】:Hibernate - ThreadLocal<EntityManager> vs EntityManager per operationHibernate - 每个操作的 ThreadLocal<EntityManager> 与 EntityManager
【发布时间】:2016-12-23 18:08:29
【问题描述】:

我使用 Hibernate 5.1.0.Final,Guice,Jersey。我有 HibernateModule,它创建 EntityManagerFactory 并管理 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() 用于清除持久性上下文并强制从数据库中查询最新数据。 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);
    }
}

以前我曾尝试实现一个解决方案,该解决方案在每个数据库操作上提供新的EntityManager,但它会导致一些副作用,例如“传递给持久化的分离实体”。

ThreadLocal&lt;EntityManager&gt; 重用EntityManager 是一种好习惯吗?这种实现有什么潜在的缺点吗?

【问题讨论】:

    标签: java hibernate jpa entitymanager thread-local


    【解决方案1】:

    它应该可以正常工作。 Spring Framework 将 ThreadLocal 类用于 EntityManager。来自参考:

    Spring 可以轻松创建 Session 并将其绑定到当前 线程透明

    如果你想重用 EntityManager 实例,你应该记住 JPA 提示 PersistenceContextTypeFlushModeType

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-24
      • 2015-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多