JPA + Hibernate CreateNativeQuery выполняет обновление дважды - PullRequest
0 голосов
/ 21 марта 2019

У меня есть проект, полученный из Jhipster, то есть SpringBoot с JPA и Hibernate. По некоторым причинам я должен реализовать постоянство на БД PostgreSQL, используя entityManager и код SQL напрямую.

У меня обычный контроллер покоя:

@GetMapping("/enterprises/{vat}")
public ResponseEntity<Enterprise> getEnterpriseByVat(...

, который звонит:

Optional<Enterprise> enterpriseDTO = enterpriseService.findEnterprise(vat, vatRequestBean);

так вот это EnterpriseService:

public interface EnterpriseService {

    Optional<Enterprise> findEnterprise(String vat, VatRequestBean vatRequestBean);

Его реализация:

@Service
@Transactional
public class EnterpriseServiceImpl implements EnterpriseService {

    private final EnterpriseRepository enterpriseRepository;

    public EnterpriseServiceImpl(EnterpriseRepository enterpriseRepository) {
        this.enterpriseRepository = enterpriseRepository;
    }

    @Override
    public Optional<Enterprise> findEnterprise(String vat, VatRequestBean vatRequestBean) {
        return enterpriseRepository.findEnterprise(vat, vatRequestBean);
    }

В то время как на стороне репозитория у меня есть:

@Repository
public interface EnterpriseRepository extends JpaRepository<RequestCache, Long>, EnterpriseRepositoryCustom {}
}

С пользовательским репозиторием:

public interface EnterpriseRepositoryCustom {

    Optional<Enterprise> findEnterprise(String vat, VatRequestBean vatRequestBean);
}

и, наконец, реализация:

@Repository
@Transactional(readOnly = true)
public class EnterpriseRepositoryImpl implements EnterpriseRepositoryCustom {

    @PersistenceContext
    EntityManager entityManager;

    @Autowired
    RestTemplate restTemplate;

    ...

    private void saveRequestCache(RequestCache requestCache) {
        if (requestCache.getId() != null) {
            entityManager.createNativeQuery(
                "update enterprises_data.requests_cache set " +
                    "vat = ? ," +
                    "json_data = ? ," +
                    "request_result = ? ," +
                    "stack_trace_error = ? ," +
                    "last_update_user = ? ," +
                    "last_update_application = ? " +
                    "where Id_requests_cache = ? ")
                .setParameter(1, requestCache.getVat())
                .setParameter(2, requestCache.getJsonData())
                .setParameter(3, requestCache.getRequestResult())
                .setParameter(4, requestCache.getStackTraceError())
                .setParameter(5, requestCache.getLastUpdateUser())
                .setParameter(6, requestCache.getLastUpdateApplication())
                .setParameter(7, requestCache.getId())
                .executeUpdate();
        } else {
            entityManager.createNativeQuery(
                "insert into enterprises_data.requests_cache (" +
                    "json_data, vat, inserting_application, last_update_application, request_result, " +
                    "stack_trace_error, inserting_user, last_update_user) " +
                    "values (?,?,?,?,?,?,?,?) ")
                .setParameter(1, requestCache.getJsonData())
                .setParameter(2, requestCache.getVat())
                .setParameter(3, requestCache.getInsertingApplication())
                .setParameter(4, requestCache.getInsertingApplication())
                .setParameter(5, requestCache.getRequestResult())
                .setParameter(6, requestCache.getStackTraceError())
                .setParameter(7, requestCache.getInsertingUser())
                .setParameter(8, requestCache.getInsertingUser())
                .executeUpdate();
        }
    }

Логика довольно проста: сохраните первый раз, обновите второй. Сущность:

@Entity
@Table(name = "requests_cache", schema = "enterprises_data")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class RequestCache implements Serializable {

    @Id
    @Column(name = "id_requests_cache")
    private Long id;
    @Column(name = "vat")
    private String vat;
    @Column(name = "json_data")
    private String jsonData;
    . . .

Странно, что при вставке кажется, что createNativeQuery выполняет именно этот запрос:

     "insert into enterprises_data.requests_cache (" +
     "json_data, vat, inserting_application, last_update_application, request_result, " +
     "stack_trace_error, inserting_user, last_update_user) " +
     "values (?,?,?,?,?,?,?,?) "

как журнал подтверждает:

Hibernate: insert into enterprises_data.requests_cache (json_data, vat, inserting_application, last_update_application, request_result, stack_trace_error, inserting_user, last_update_user) values (?,?,?,?,?,?,?,?) 

Но при обновлении JPA выполняет это:

 "update enterprises_data.requests_cache set " +
 "vat = ? ," +
 "json_data = ? ," +
 "request_result = ? ," +
 "stack_trace_error = ? ," +
 "last_update_user = ? ," +
 "last_update_application = ? " +
 "where Id_requests_cache = ? "

только после другого в качестве отчета журнала (обратите внимание на начало 'set vat =?' во втором и что первое имеет все поля в список):

Hibernate: update enterprises_data.requests_cache set inserting_application=?, inserting_date=?, inserting_user=?, json_data=?, last_update_application=?, last_update_date=?, last_update_user=?, request_result=?, stack_trace_error=?, vat=? where id_requests_cache=?

Hibernate: update enterprises_data.requests_cache set vat = ? ,json_data = ? ,request_result = ? ,stack_trace_error = ? ,last_update_user = ? ,last_update_application = ? where Id_requests_cache = ?

Так что я не могу понять, почему JPA выполняет обновление дважды, в то время как вставка, кажется, работает хорошо ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...