В приложении Spring Boot с источником данных HikariCP я выполняю 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 Session закрывается случайным образоми транзакция ожидает 30 секунд (значение таймаута по умолчанию для транзакций HikariCP), прежде чем get get Session закрывается ошибка (или currentPersistenceContext имеет значение null, если я использовал getCurrentSession () вместо openSesssion ()).
Прежде всего, я изменил открытый сеансполучить функцию getCurrentSession.Но мне также нужно указать контекст с помощью @PersistenceContext или hibernate.current_session_context_class = thread в hibernate.cfg.xml.Я читал, что это свойство лучше использовать со значением по умолчанию.Также я указываю 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.Теперь все работает нормально.Но это правильные модификации?Все функции работают с методом execute QueryExecutor, аннотированным @Transactional.Как я понял, в этом случае не требуется beginTransaction ().Но нужно ли закрывать entityManager после execute ()?
SessionFactory, используемый с Hibernate без JPA и EntityManager, используемый с технологиями Hibernate JPA?
Как решить проблему без использования EntityManager?