Я предполагаю, что вы позволяете пользователю выбрать адрес из его списка адресов (Person # address), поэтому, когда вы отправляете свой заказ, он содержит адрес, который уже находится в базе данных, включая id
, который создает связь, не создать запись:
{
user: {
id: 10,
email: "user@stackoverflow.com"
},
address: {
id: 10,
street: "5th Av"
}
}
Если вы хотите, чтобы " имел копию адреса ", вам следует сначала обновить ваши отношения в классе Order
, например:
@OneToOne(cascade = CascadeType.ALL)
private Address address;
Затем отправьте адрес без id
, который будет указывать ваш репозиторий для создания новой записи в базе данных.
Опция Json:
{
user: {
id: 10,
email: "user@stackoverflow.com"
},
address: {
street: "5th Av", ...
}
}
Или, удалив id
на контроллере:
@PostMapping("/submit-order")
public Order submitOrder( @RequestBody Order order) {
// Remove Order#id to detatch current record and enforce create a new one
order.getAddress().setId(null);
return this.orderRepository.save(order);
}
Таким образом, ваш заказ имеет эксклюзивную копию адреса.
ОШИБКА: org.springframework.orm.jpa.JpaSystemException с сообщением «Адрес был изменен с 1 на ноль»
Если вы получили эту ошибку, это потому, что вы удаляете идентификатор сущности в рамках транзакции или сеанса. Вы должны создать копию сущности из этой области или использовать менеджер сущностей для отсоединения сущности, вот пример .
@ встраиваемое решение
Другим решением было бы использовать вместо этого встраиваемый объект, чтобы вы могли хранить поля адресов в таблице заказов, но иметь их как составной объект:
Сначала вы создаете объект адреса заказа со всеми обязательными полями и помечаете его @Embeddable
аннотацией:
@Embeddable
public class AddressOrder {
@Column("street")
private String street;
@Column("postal_code")
private String po;
@Column("city")
private String city;
@Column("country")
private String country;
// Getters and setters
}
Затем вы используете объект в таблице заказов в качестве атрибута и помечаете его аннотацией @Embedded
.
@Entity
public class Orders {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
@Embedded
private AddressOrder address;
// Getters and setters
}
Вам нужно выбрать решение в соответствии с подходом базы данных, который вы хотите использовать.