Как заставить коммит сущность в режиме @Transactional - PullRequest
0 голосов
/ 02 июня 2018

Я использую Spring данные jpa и jdbc (используя entityManager.unwrap (Session.class)) соединение.
Мой запрос проходит через 3 метода.1-й -> 2-й -> 3-й.
1-й и 3-й помечены @ Transactional.
В 1-м и 2-м методе сохранение сущности через репозиторий JPA CRUD.
В 3-м методе используется базовый запрос jdbc для получения значений, сохраненных в2-й метод.
Как мы знаем в @Transaction объекты не фиксируются в базе данных, пока JPA не завершит транзакцию.
Я также использовал saveAndFlush во 2-м методе, но не могу увидеть получение обновленных значений в методе 3 с использованием запроса jdbc.

1-й метод - update ()

@Transactional
@Override
public ApiResponse update(RequestInput input) {
    ApiResponse response = doRestOfWork(input);   // calling 2nd method
    // .... some other entity save....
}

2-й метод - doRestOfWork () : установка состояния = true и вызов метода saveAndFlush

@Override
public ApiResponse doRestOfWork(Request request) {
    Insight insight = insightRepository.findOne(request.getTypeId());
    insight.setStatus(true);
    insightRepository.saveAndFlush(insight);

    processOperation();    // calling 3rd method
}

3-й метод - processOperation () : получение обновленного значения состояния через соединение jdbc.

@Transactional
public void processOperation() {
Connection conn = null;
        SessionImplementor sessionImpl = (SessionImplementor) entityManager.unwrap(Session.class);
        try {
            conn = sessionImpl.getJdbcConnectionAccess().obtainConnection();
            Connection conn = null;
            String stmt = "SELECT status from insight";
            PreparedStatement ps = conn.prepareStatement(stmt);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
               boolean value = rs.getBoolean(status);   // returning false, i want this to return true as already set true in 2nd method and called saveAndFlush 
        }
    } catch (SQLException ex) {
    } finally {
        JdbcUtility.closeResources(conn, ps, rs);
    }
}

InsightRepository расширяет JpaRepository

@Repository
public interface InsightRepository extends JpaRepository<Insight, Long> {}

Я хочу обновить значение состояния (которое имеет логическое значение true - обновлено в методе 2) в методе 3. Как этого добиться?

Обновить

ищуОн много читал и не думал, что если метод аннотирован @ Transactional , вы можете зафиксировать изменения до завершения транзакции JPA.Поэтому решение состоит в том, чтобы удалить аннотацию @ Transactional и использовать entityManager.getTransaction (), если вы хотите контролировать транзакцию JPA.

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Создайте метод (4-й метод) для обновления с @Transactional(propagation = Propagation.REQUIRES_NEW) аннотацией в bean-компоненте, отличном от 2-го метода, и измените второй метод как вызывающий 4-й метод следующим образом:

@Component //or Service etc..
public class AnotherBean{

  @Transactional(propagation = Propagation.REQUIRES_NEW)
  public void doUpdateWork(Request request){
    Insight insight = insightRepository.findOne(request.getTypeId());
    insight.setStatus(true);
    insightRepository.save(insight);
  }
} 

и

    @Override
    public ApiResponse doRestOfWork(Request request) {
        anotherBean.doUpdateWork(request);
        processOperation();    // calling 3rd method
    }
0 голосов
/ 02 июня 2018

Если вы хотите контролировать транзакцию, не используйте @Transactional

em; //entityManager

Transaction tx=em.getTransaction();
try{
   tx.begin();
   //do work
   tx.commit(); // comminted transaction 
 // start another transaction if you need to, doo more work etc.
...
}

Это самый основной и фундаментальный блок кода для использования JPA для атомарных операций.

Также нетнужно unwrap менеджер сущностей, использовать чистый JPA.Развертывая, вы привязываете текущую реализацию к провайдеру JPA, что противоречит идее JPA о независимости от основного провайдера реализации JPA.Другими словами, он перестанет работать, если по каким-то причинам Spring изменит свою реализацию JPA с Hibrnate на eg.EclipseLink.

...