Я использую Spring Data (версия 1.13.9.RELEASE) и имею CrudRepository под названием myRepository. Я вызываю myRepository.save(myObject), чтобы перезаписать существующий экземпляр myObject в базе данных, и я указываю некоторые поля myObject как null.
Например:
{
"prop1": "val1",
"prop2": null,
"prop3": "val3"
}
Когда я вызываю myRepository.save(myObject) и читаю возвращаемое значение, все поля myObject, которые я установил как null, возвращаются как null (в этом примере prop2).
Однако значение для prop2 в базе данных НЕ является null после вызова save() - оно все еще имеет предыдущее значение до того, как я вызвал save().
На самом деле это то поведение, которое я хочу в данной конкретной ситуации (игнорировать значения null при вызове myRepository.save()), но я бы хотел, чтобы возвращаемое значение save() отражало то, что на самом деле находится в базе данных после операции, а не только возвращало обновленные поля и поля настройки, указанные как null в null или их значения по умолчанию (например, false в случае логического.
Это ожидаемое поведение CrudRepository в поведении save()?
Есть шанс, что это не так. Я использую DynamoDB. Возможно, следует установить в полях значение null. Однако, если это не так, я думаю, что CrudRepository должен в основном повторно запрашивать базу данных при вызове save(), чтобы вернуть самые последние значения. Я не уверен, где он видит эти значения как null (поскольку они не null в Dynamo)
Второй вопрос .. вы используете Hibernate?
@PranjalGore Да, я
Хорошо. Итак, вам нужно сначала получить самый последний объект, это привязывает объект к постоянному состоянию. Во-вторых, обновите объект (пока он все еще находится в постоянном состоянии) и, наконец, вызовите save.
Я также не так хорошо знаком с Spring Data или Dynamo, но я согласен, что он не должен возвращать значения из базы данных, если вы явно не запросите его повторно. Я думаю, вам следует либо вызвать myRepository.saveAndFlush (), либо использовать myRepository.merge ()




Чтобы понять проблему, вам нужно немного разобраться в жизненном цикле объекта Hibernate.
Жизненный цикл объекта Hibernate состоит из следующих состояний: 1. Переходное состояние 2. Постоянное состояние 3. Обособленное состояние и т. д.
Когда вы создаете новый объект, он находится в переходном состоянии, а Hibernate не имеет средств обнаружения объектов, присутствующих / созданных в переходном состоянии.
Когда вы вызываете save()saveOrUpdate(), объект переходит из переходного состояния в постоянное, и теперь Hibernate начнет отслеживать все изменения, внесенные в объект (но объект еще не записан в базу данных).
Итак, в вашем случае, поскольку объект не находится в постоянном состоянии, спящий режим не может его распознать и запустит (скорее всего) запрос insert. Однако, если бы объект уже находился в постоянном состоянии, спящий режим знал бы, что некоторые поля изменились, и, следовательно, запустит запрос update.
Вот почему вам нужно убедиться, что объект находится в постоянном состоянии, если вы хотите, чтобы спящий режим запускал запрос update.
Это означает, что транзакция еще не завершена и все изменения находятся только в кеше. Для принудительного обновления вы можете вызвать entityManager.flush() или переместить всю необходимую логику в отдельный общедоступный метод другой службы или менеджера и аннотировать его как @Transactional.
Просто интересно, правильно ли обновляется ваша база данных?