Управление сессиями Hibernate в JPA-приложении Spring Boot с источником данных HikariCP - PullRequest
0 голосов
/ 25 сентября 2018

В приложении 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?

1 Ответ

0 голосов
/ 25 сентября 2018

Вам не нужно закрывать транзакции вручную, если вы используете аннотацию @Transactional.

Но если вы используете его, я рекомендую вам попытаться использовать Репозитории JPA и обернуть @Transactional аннотацией только методы бизнес-логики.

В этом случаевам больше не понадобится EntityManager, и вы сможете создавать собственные сложные запросы с помощью JpaSpecificationExecutor и JPA Criteria API Queries .

...