首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Hibernate -每次操作ThreadLocal<EntityManager>与EntityManager的比较

Hibernate -每次操作ThreadLocal<EntityManager>与EntityManager的比较
EN

Stack Overflow用户
提问于 2016-08-17 07:30:53
回答 1查看 931关注 0票数 2

我使用Hibernate 5.1.0,Guice,Guice,泽西。我有HibernateModule,它创建EntityManagerFactory并管理EntityManager实例:

代码语言:javascript
复制
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()用于清除持久化上下文,并强制从dabatase中查询最新数据。GenericDAO从HibernateModule接收注入的EntityManager。主要方法:

代码语言:javascript
复制
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,但它会产生一些副作用,比如“通过独立实体传递给持久化”。

EntityManager重用ThreadLocal<EntityManager>是一个很好的实践吗?这个实现有什么潜在的缺点吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-17 09:57:43

它应该能正常工作。Spring正在为ThreadLocal使用EntityManager类。参考资料:

Spring使创建会话和将会话透明地绑定到当前线程变得更加容易。

如果您想要重用PersistenceContextType实例,您应该记住JPA提示、FlushModeType和EntityManager。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38990608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档