@Transactional
должен сам отражать изменения, внесенные в сущность в базе данных. Я создаю приложение, в котором клиент может создать сущность Car, которая выглядит так (метод update
позже используется PUT, не обращайте внимания на свойство brand
):
@Entity
@Table(name = "cars")
public class Car {
@Id
@GeneratedValue(generator = "inc")
@GenericGenerator(name = "inc", strategy = "increment")
private int id;
@NotBlank(message = "car name`s must be not empty")
private String name;
private LocalDateTime productionYear;
private boolean tested;
public Car() {
}
public Car(@NotBlank(message = "car name`s must be not empty") String name, LocalDateTime productionYear) {
this.name = name;
this.productionYear = productionYear;
}
@ManyToOne
@JoinColumn(name = "brand_id")
private Brand brand;
public int getId() {
return id;
}
void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public LocalDateTime getProductionYear() {
return productionYear;
}
public void setProductionYear(LocalDateTime productionYear) {
this.productionYear = productionYear;
}
public boolean isTested() {
return tested;
}
public void setTested(boolean tested) {
this.tested = tested;
}
public Brand getBrand() {
return brand;
}
void setBrand(Brand brand) {
this.brand = brand;
}
public Car update(final Car source) {
this.productionYear = source.productionYear;
this.brand = source.brand;
this.tested = source.tested;
this.name = source.name;
return this;
}
}
В моем приложении клиент может создать новый Car или обновить существующий с помощью метода PUT.
Мой контроллер:
@RestController
public class CarController {
private Logger logger = LoggerFactory.getLogger(CarController.class);
private CarRepository repository;
public CarController(CarRepository repository) {
this.repository = repository;
}
//The client can create a new resource or update an existing one via PUT
@Transactional
@PutMapping("/cars/{id}")
ResponseEntity<?> updateCar(@PathVariable int id, @Valid @RequestBody Car source) {
//update
if(repository.existsById(id)) {
repository.findById(id).ifPresent(car -> {
car.update(source); //it doesn`t work
//Snippet below works
//var updated = car.update(source);
//repository.save(updated);
});
return ResponseEntity.noContent().build();
}
//create
else {
var result = repository.save(source);
return ResponseEntity.created(URI.create("/" + id)).body(result);
}
}
}
Когда я создаю новую машину, она работает. Однако, как описано в коде, при отсутствии метода сохранения объект не изменяется, хотя я получаю статус 204 (нет содержимого). Когда есть метод сохранения, он работает нормально. Вы знаете, почему это так?
Один из пользователей попросил у меня сущность Brand
. Я пока не создал ни одного объекта Brand
, но по существу Car
может принадлежать определенному Brand
в моем приложении. Пока ни один Car
не принадлежит ни одному Brand
. Вот эта сущность:
@Entity
@Table(name = "brands")
public class Brand {
@Id
@GeneratedValue(generator = "i")
@GenericGenerator(name = "i", strategy = "increment")
private int id;
@NotBlank(message = "brand name`s must be not empty")
private String name;
private LocalDateTime productionBrandYear;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "brand")
private Set<Car> cars;
@ManyToOne
@JoinColumn(name = "factory_id")
private Factory factory;
public Brand() {
}
public int getId() {
return id;
}
void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public LocalDateTime getProductionBrandYear() {
return productionBrandYear;
}
public void setProductionBrandYear(LocalDateTime productionBrandYear) {
this.productionBrandYear = productionBrandYear;
}
public Set<Car> getCars() {
return cars;
}
public void setCars(Set<Car> cars) {
this.cars = cars;
}
public Factory getFactory() {
return factory;
}
public void setFactory(Factory factory) {
this.factory = factory;
}
}
Brand
сущность? - person code_mechanic   schedule 29.03.2021brand
имеет значение null, поэтому это немного странно для меня, поскольку я даже не создал никакого объекта бренда, и моя единственная цель на данный момент — обновить мой автомобиль, который не связан с Бренд. Я не хочу вносить какие-либо изменения в сущность "Бренд", поскольку ее не существует. - person Monoxyd   schedule 29.03.2021ifPresent
или нет, добавьте журналы для гибернации и проверьте, выполняются ли запросы. - person code_mechanic   schedule 29.03.2021ifPresent
вызывается. Я пытаюсь добавить журналы для спящего режима, но мне это не удается. В любом случае, обычно запросы запускаются, потому что у меня проблема только с обновлением через PUT. - person Monoxyd   schedule 29.03.2021@EnableTransactionManagement
, чтобы аннотация@Transactional
заработала? - person Nikolai Shevchenko   schedule 30.03.2021