Могу ли я сохранить и прочитать сохраненное значение в @Transactional аннотированном методе SpringBoot?

#java #postgresql #spring-boot #hibernate

#java #postgresql #весенняя загрузка #спящий режим

Вопрос:

Насколько я понимаю, изменения, внесенные в рамках одной транзакции, должны быть видны в этой транзакции, хотя передача данных не зафиксирована.

Но у меня возникает проблема при попытке прочитать значения после сохранения в @Transactional аннотированном методе. Когда извлекаются сохраненные строки, обновленные значения отсутствуют. Так ли это, как это должно произойти, или я делаю что-то не так? Вот как выглядит мой код

DetailService.java

 @Slf4j
@Service
public class DetailService {

    @Autowired
    private DetailRepository detailRepository;
   
    @Transactional
    public void updateDetails(List<DetailDTO> details, String sequence){
        updateOne(details);
        List<DetailDTO> updatedDetails = detailRepository.findAllBySequence(sequence);
        updatedDetails.forEach(ud -> log.info(ud.getOne())); // this prints null although this should be updated from previous method
    }

    private void updateOne(List<DetailDTO> details){
        details.forEach(detail -> {
            Optional<DetailEntity> dOpt = detailRepository.findById(detail.getId());
            dOpt.ifPresent(d -> {
                d.setOne(detail.getOne());
                detailRepository.save(d); // this is not required as this should be save on tx commit but right now I have it on my code
            });
        });
    }

}
  

DetailRepository.java

 @Repository
public interface DetailRepository extends JpaRespository<DetailEntity, Long> {
    List<DetailEntity> findAllBySequence(@Param("sequence") String sequence);
}
  

application.yml

 # Datasource Settings
  datasource:
    driver-class-name: org.postgresql.Driver
    url: jdbc:postgresql://db.xxxxx.co:5432/DatabaseName
    username: USERNAME
    password: PASSWORD
    #maxActive: 5 (This can be removed I guess. It has no effect or is deprecated)

    # Connection Pool Settings
    hikari:
      pool-name: xxxxxx-hikari
      maximum-pool-size: 5
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000

  # JPA Settings
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: none
    properties:
      hibernate:
        physical_naming_strategy: c.s.l.u.util.PhysicalNamingStrategyImpl
        default_schema: "DEFAULT_SCHEMA"
        temp:
          use_jdbc_metadata_defaults: false
        proc:
          param_null_passing: true
      org:
        hibernate:
          envers:
            default_schema: "AUDIT"
            store_data_at_delete: true
    database-platform: org.hibernate.spatial.dialect.postgis.PostgisDialect
  

Как я уже упоминал в комментариях к коду, я получаю нулевые значения, когда пытаюсь прочитать данные сразу после их обновления. Я использую Sprint Boot 2.2.6 с базой данных Postgres 10.12

Комментарии:

1. Вы уверены, что обновляете и выбираете один и тот же объект? вы обновляете объекты на основе идентификатора и пытаетесь выбрать «обновленные» объекты по последовательности. Вы уверены, что они оба имеют одинаковую последовательность? Или, может быть, вы также хотите обновить объекты значением последовательности? Запишите сведения, которые вы извлекли при сохранении, и те, которые вы пытаетесь показать и сравнить.

2. @JorgeCampos Да, я уверен, что я обновляю и выбираю один и тот же объект. Последовательность на самом деле является внешним ключом, ссылающимся на родительскую таблицу. Я использую идентификатор для обновления, поскольку мне нужно обновить эти записи отдельными данными.

3. Я заметил одну странную вещь: ваш метод репозитория возвращается List<DetailEntity> , и в вашем методе вы назначаете этот вызов List<DetailDTO> , возможно, есть проблема в преобразовании?