Я хочу обновить таблицу с помощью spring-jpa
Это мой класс сущности
public class RewardEntity {
@Id
@Column(name = "reward_id", columnDefinition = "bigserial")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long rewardId;
@Column(name = "reward_title", nullable = false)
private String rewardTitle;
@Column(name = "reward_text")
private String rewardText;
@Column(name = "reward_type", nullable = false)
private String rewardType;
@Column(name = "reward_for_code", nullable = false)
private String rewardFor;
@Column(name = "reward_from_date", nullable = false)
private OffsetDateTime rewardFromDate;
@Column(name = "reward_to_date", nullable = false)
private OffsetDateTime rewardToDate;
@Column(name = "is_display_on", nullable = false)
private Boolean isDisplayOn;
@Column(name = "created_id", length = 50, nullable = false)
private String createdId;
@Column(name = "updated_id", length = 50)
private String updatedId;
@Column(name = "created_date", columnDefinition = "timestamptz", nullable = false)
private OffsetDateTime createdDate;
@Column(name = "last_modified_date", columnDefinition = "timestamptz")
private OffsetDateTime lastModifiedDate;
}
У меня есть PutMapping весенние ботинки API, которые опускаются ниже Json Input
{
"rewardId": 53,
"rewardTitle": "Reward is Allocated",
"rewardText": "Reward allocated for your recent purchase with our shop located at ABC-Mall",
"rewardType": "Informational",
"rewardFor": "Customer",
"rewardFromDate": "2019-04-12T00:00:00+05:30",
"rewardToDate": "2019-04-15T00:00:00+05:30",
"isDisplayOn": false
}
Мой контроллер принимает объект Principal как для творчество, так и для обновление таблицы rewards
@PutMapping
public ResponseEntity<RewardsResponse> updateRewards(Principal updatedPrincipal,
@RequestBody RewardUpdateRequest RewardUpdateRequest) {
Но я не буду отправлять свои createdId или updatedId из моего Angular-UI. Поэтому, когда я пытаюсь вставить обновленный объект в таблицу, используя приведенный ниже код сервисного уровня
public RewardEntity updateReward(Principal principal, rewardEntity rewardEntity) {
String updatedId = null != principal ? principal.getName() : "defaultUpdatedId";
rewardEntity.setUpdatedCdsId(updatedId);
rewardEntity.setLastModifiedDate(OffsetDateTime.now());
return rewardRepository.save(rewardEntity);
}
Я получаю следующую ошибку
could not execute statement; SQL [n/a]; constraint [created_id]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
Я предполагаю, что RewardEntity обновляется в той же строке, сопоставляя ID, который мы передаем, и обновляем только fields, который я установил, и не трогая остальные поля...
Должен ли я сначала получить свой объект RewardEntity из БД на основе идентификатора, а затем обновить поверх него ?? Это заставляет код дважды подключать БД для каждого обновления.
Запросите ваши материалы, пожалуйста
Я бы сначала получил ссылочный объект, используя updatedId
RewardEntity rewardEntity = rewardRepository.getOne(updatedId )
обновить этот объект в соответствии с вашими требованиями
rewardEntity.setLastModifiedDate(OffsetDateTime.now());
и, наконец, используйте сохранить, чтобы обновить это.
return rewardRepository.save(rewardEntity);
getOne() возвращает ссылку на сущность и внутренне вызывает EntityManager.getReference() метод. Он всегда будет возвращать прокси без обращения к базе данных (ленивое извлечение).