Spring 使用 HikariCP 数据源引导 JPA 应用程序中的 Hibernate 会话管理
Hibernate sessions management in Spring Boot JPA application with HikariCP data source
在 Spring 使用 HikariCP 数据源启动应用程序中,我使用 helper class:
执行了 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;
}
它工作正常,但是当我开始广泛使用 class 时,应用程序开始冻结,因为 Hibernate Session 随机关闭并且事务等待 30 秒(HikariCP 事务的默认超时值)在 get Session is closed 错误之前(或者 currentPersistenceContext 为空,如果我使用 getCurrentSession() 而不是 openSession()).
首先,我把open session改成了getCurrentSession函数。但我还需要在 hibernate.cfg.xml 中使用 @PersistenceContext 或 hibernate.current_session_context_class=thread 指定上下文。
我读到这个 属性 最好使用默认值。
我还指定 hibernate.connection.release_mode=AFTER_TRANSACTION。
但这并不能解决问题。
毕竟我是这样改class的:
@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 查询。
现在它工作正常。但这是正确的修改吗?
所有函数都与使用@Transactional 注释的QueryExecutor 的execute 方法一起工作。正如我所理解的那样,在那种情况下不需要 beginTransaction() 。
但是我需要在 execute() 之后关闭 entityManager 吗?
SessionFactory 与不带 JPA 的 Hibernate 一起使用,EntityManager 与 Hibernate JPA 技术一起使用?
如何在不使用 EntityManager 的情况下解决问题?
如果您使用 @Transactional
注释,则无需手动关闭交易。
但如果你使用它,我会建议你尝试使用 JPA Repositories 并在 @Transactional
注释中仅包含业务逻辑方法。
在这种情况下,您将不再需要 EntityManager
,您将能够使用 JpaSpecificationExecutor and JPA Criteria API Queries.
创建自定义复杂查询
在 Spring 使用 HikariCP 数据源启动应用程序中,我使用 helper class:
执行了 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;
}
它工作正常,但是当我开始广泛使用 class 时,应用程序开始冻结,因为 Hibernate Session 随机关闭并且事务等待 30 秒(HikariCP 事务的默认超时值)在 get Session is closed 错误之前(或者 currentPersistenceContext 为空,如果我使用 getCurrentSession() 而不是 openSession()).
首先,我把open session改成了getCurrentSession函数。但我还需要在 hibernate.cfg.xml 中使用 @PersistenceContext 或 hibernate.current_session_context_class=thread 指定上下文。 我读到这个 属性 最好使用默认值。 我还指定 hibernate.connection.release_mode=AFTER_TRANSACTION。 但这并不能解决问题。
毕竟我是这样改class的:
@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 查询。 现在它工作正常。但这是正确的修改吗? 所有函数都与使用@Transactional 注释的QueryExecutor 的execute 方法一起工作。正如我所理解的那样,在那种情况下不需要 beginTransaction() 。 但是我需要在 execute() 之后关闭 entityManager 吗?
SessionFactory 与不带 JPA 的 Hibernate 一起使用,EntityManager 与 Hibernate JPA 技术一起使用?
如何在不使用 EntityManager 的情况下解决问题?
如果您使用 @Transactional
注释,则无需手动关闭交易。
但如果你使用它,我会建议你尝试使用 JPA Repositories 并在 @Transactional
注释中仅包含业务逻辑方法。
在这种情况下,您将不再需要 EntityManager
,您将能够使用 JpaSpecificationExecutor and JPA Criteria API Queries.