Получение javax.persistence.TransactionRequiredException: в приложении Spring Boot не выполняется транзакция

Я использую JPA + Hibernate в своем приложении Spring Boot. Мой метод обслуживания выглядит следующим образом: -

    @Override
    public Employee createEmployee(Employee employeeModel) {
        logger.debug("entered the createEmployee method");
        Optional<Employee> optionalEmployee = repository.findByEmpShortNm(employeeModel.getEmpShortNm());
        logger.debug("Fetched the optional");
        if(optionalEmployee.isPresent())
            return optionalEmployee.get();
        else {
            logger.debug("Persisting employee.....");
            return repository.save(employeeModel);
        }
    }

EmployeeRepository.java имеет следующий метод: -

@Lock(LockModeType.PESSIMISTIC_WRITE)
Optional<Employee> findByEmpShortNm(String uuid);

Мое приложение работало нормально, пока я не применил Lock annotation к моему методу репозитория. После применения метода Lock createEmployee возникает следующее исключение: -

javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1560)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1533)
at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1581)
at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getSingleResult(CriteriaQueryTypeQueryAdapter.java:111)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:196)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:88)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:154)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:142)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor$QueryMethodInvoker.invoke(QueryExecutorMethodInterceptor.java:195)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:152)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

Почему он не может получить транзакцию, хотя он работал нормально, когда я не использовал @Lock Annoation. Какая связь ч/б @Lock и Transaction.

Я был бы признателен, если бы какая-либо ссылка могла быть предоставлена.


person Manish    schedule 29.07.2020    source источник


Ответы (1)


Решение: вы должны аннотировать свой сервис с помощью @Transactional

Когда блокировка включена явно и нет активной транзакции, базовая реализация JPA выдаст исключение TransactionRequiredException.

Это как-то логично, когда у тебя нет своей транзакции, зачем тебе блокировать объект сущности? У вас должен быть метод транзакции вне репозитория, во время которого вы хотите заблокировать объект объекта.

Прочтите эту статью:

https://www.baeldung.com/java-jpa-transaction-locks

person Tashkhisi    schedule 29.07.2020
comment
означает ли это, что когда мы не делаем явную блокировку, JPA/Hibernate автоматически создает транзакцию, но когда мы отмечаем явную блокировку, мы должны пометить с помощью Transactional для создания транзакции. - person Manish; 29.07.2020
comment
тогда транзакционная аннотация также может быть применена к тому же методу репозитория, потому что транзакция требуется для выполнения db. Правильно ? - person Manish; 29.07.2020
comment
Я только что добавил несколько примечаний к своему ответу, пожалуйста, прочитайте его еще раз и дайте мне знать, если у вас есть какие-либо вопросы. - person Tashkhisi; 29.07.2020