当前位置: 首页 > 知识库问答 >
问题:

用HikariCP数据源实现Spring Boot JPA应用程序中的Hibernate会话管理

葛驰
2023-03-14

在使用HikariCP dataSource的Spring Boot应用程序中,我使用helper类执行了HQL查询:

public class QueryExecutor {
    private Session session;

    @Autowired
    private SessionFactory sessionFactory;

    public QueryExecutor getConnection() {
        session = sessionFactory.openSession();
        session.beginTransaction();

        return this;
    }

    public void closeConnection() {
        session.getTransaction().commit();
        session.close();
    }

    public List execute(String hql, Long limit, Long offset) {
        getConnection();

        Query query = session.createQuery(hql);

        List list = query.list();

        closeConnection();

        return list;
    }

它工作正常,但是当我开始广泛使用类时,应用程序启动冻结,因为Hibernate会话随机关闭,事务等待30秒(HikariCP事务的默认超时值),然后get会话关闭错误(如果我使用getCurrentSession()而不是openSesssion(),则currentPersistenceContext为null)。

首先,我将open session更改为getCurrentSession函数。但是我还需要在hibernate.cfg.xml中用@persistenceContext或hibernate.current_session_context_class=thread指定上下文。我读到这个属性最好与默认值一起使用。另外,我指定hibernate.connection.release_mode=after_transaction。但这并不能解决问题。

毕竟,我是这样换班的:

@PersistenceContext
    private EntityManager entityManager;

    @Transactional
    public List execute(String hql, Long limit, Long offset) {
        Query query = entityManager.createQuery(hql);    
        return query.getResultList();
    }

并使用javax.persistence.query代替Hibernate查询。现在工作正常了。但这是正确的修改吗?所有函数都使用QueryExecutor的execute方法,并用@Transactional注释。正如我所认为的,在这种情况下,不需要beginTransaction()。但是我需要在execute()之后关闭entityManager吗?

SessionFactory与没有JPA的Hibernate一起使用,而EntityManager与Hibernate JPA技术一起使用?

共有1个答案

邓子濯
2023-03-14

如果使用@transactional注释,则不需要手动关闭事务

但是如果您使用它,我会提醒您尝试使用JPA存储库,并在@transaction注释中只包装业务逻辑的方法。

在这种情况下,您将不再需要EntityManager,并且可以使用JpaSpecificationExecutor和JPA Criteria API查询创建自定义复杂查询。

 类似资料:
  • 我在GWT应用程序中使用hibernate,其中我有一个单独的客户机/服务/业务/dao层。 服务/业务层使用dao层获取/更新用于请求处理的模型。问题是,我遵循DOA类方法中打开/关闭hibernate会话的反模式。 一般的Hibernate指南似乎建议,我们应该有一个请求范围的会话。这可以在几个地方完成,比如servlet过滤器或服务层。我们可以打开会话并将其注入到DAO层,并在完成请求之前在

  • 问题内容: 您如何在Java Desktop Swing应用程序中进行Hibernate会话管理?您是否使用一个会话?多个会议? 以下是有关此主题的一些参考资料: http://www.hibernate.org/333.html http://blog.schauderhaft.de/2008/09/28/hibernate-sessions-in-two-tier-rich-client-ap

  • 问题内容: 我目前正在开发我的一个(相当大的)宠物项目,这是一个Swing应用程序,它本质上需要多线程。几乎所有用户交互都可能通过Internet从某些远程服务器获取数据,因为我既不能控制这些服务器,也不能控制Internet本身,因此不可避免的是需要较长的响应时间。EDT忙时,Swing UI显然无法重绘自身,因此所有远程服务器调用都需要由后台线程执行。 我的问题: 后台线程获取的数据被本地(内

  • 我创建了简单的Java应用程序来学习Spring和hibernate集成。我做了所有的设置和应用程序也工作良好。 一切正常。但是,我想看看我的应用程序当前使用了多少会话,比如打开的连接和关闭的hibernate连接。 在Sessionfactory类中,我们使用“getStatistics”方法来检索hibernate统计数据,但这对我没有帮助。它也给了我零分。请找到下面的图片。 http://w

  • 我有一个Android应用程序,我可以在其中向一个servlet发送多部分post。但我要把电话限制在每5分钟一次。有了web表单,我就可以使用cookie了。对于android应用程序,它不是这样工作的。我怎么才能让它工作呢?

  • 问题内容: 我正在构建一个系统,其中来自客户端的每个请求都会在服务器端生成多个线程。然后,每个线程都使用一个或多个DAO(某些DAO可以同时被多个线程使用)。Spring 将所有DAO注入()到我的线程类中。每个DAO也接受注射。 什么是在这些多个DAO之间管理Hibernate会话的正确方法,这样我就不会因多线程环境而遇到问题(例如,来自不同线程的几个DAO试图同时使用同一会话)? 我在Hibe