Я реализую методы PUT для REST-API.
У меня есть POJO, похожее на следующее:
public class Brand implements Serializable {
@Column(columnDefinition = "serial")
@Generated(GenerationTime.INSERT)
@JsonIgnore
private Integer id;
@Id
@JsonProperty("brand")
private String brand;
.
.
.
}
В базе данных postgresql таблица брендов имеет следующие столбцы:
- внутренний идентификатор базы данных (SERIAL), который не должен быть виден снаружи (используется для объединения таблиц)
- бренд (ТЕКСТ), который является первичным ключом
Мой метод Service выглядит следующим образом:
public Brand updateBrand(String brand, Brand update) {
Brand b = brandRepository.findBrandByBrand(brand);
if(b == null) { //If not exists create new one
b = new Brand(null, brand);
}
else { //If exists keep id, delete old one and create new entry
if(update != null && update.getBrand() != null) {
brandRepository.delete(b);
}
ServiceUtils.copyProperties(update, b); //This is within the if clause, because brand is the only value
}
return brandRepository.save(b);
}
И контроллер будет выглядеть примерно так:
@PutMapping(value = "/brand/{brand}")
public ResponseEntity<Brand> updateBrand(@PathVariable("brand") String brand,
@RequestBody Brand update) {
Brand updated = articleNumberService.updateBrand(brand, update);
if(updated == null) {
throw new EntryCreationFailedException(brand); //self made exception
}
return new ResponseEntity<>(updated, HttpStatus.OK);
}
Теперь моя следующая проблема заключается в том, что при вызове PUT ../brand/stackoverflow
с телом:
{"brand":"StackOverflow")
удаляет старую марку stackoverflow (например, с id = 1) и создает новую с именем StackOverflow. Но при проверке базы данных столбец id увеличивается (поэтому теперь он имеет id = 2).
Я проверил, и это вызвано тем, что Hibernate все еще вызывает:
insert
into
brand
(brand)
values
(?)
Это определенно то, что я хочу, когда id равен нулю. Что происходит, например, при создании нового бренда. Но когда только переопределение бренда и id не равно нулю, я хочу, чтобы hibernate назвал это:
insert
into
brand
(id, brand)
values
(?, ?)
Я знаю, что это было бы возможно, если создать собственный метод сохранения и в экстренном случае переопределить запрос. НО я довольно оптимистичен, что это возможно без. Но я не могу найти подходящих ответов на это. У меня уже были проблемы с поиском правильных аннотаций для последовательного поведения, специфичного для postgresql.
П.С .: Я знаю, что некоторые будут кричать "почему вы выбрали Бренд в качестве первичного ключа, а не идентификатор !?" Но это только простой класс / часть базы данных. Существуют более сложные классы, которые используют точно такой же способ для внутреннего идентификатора базы данных (и действительно нуждаются в нем), но имеют несколько первичных ключей и т. Д. Так что это довольно простое представление для моей проблемы.