Hibernate: Как сохранить информацию, связанную с порядком - PullRequest
0 голосов
/ 09 марта 2019

В моем приложении пользователь размещает заказ и устанавливает адрес для выставления счета на один из сопоставленных ему адресов.Теперь в будущем он редактирует этот адрес. Поэтому мой заказ будет сопоставлен с этим обновленным адресом.

Сущность моего заказа

@Entity
public class Orders{
...

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;

@OneToOne
private Address address;
...
}

Сущность адреса

@Entity
@Table(name = "address")
public class Address {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private String address1;

...

}

Сущность лица

@Entity
public class Person{
...
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Set<Address> addresses = new HashSet<>();
...
}

Я хочу, чтобы у объекта «Заказ» была копия Адреса, как это было при создании заказа. Любые изменения в адресе пользователя в его профиле после создания заказа не должны влиять на это.Заказать.

1 Ответ

1 голос
/ 09 марта 2019

Я предполагаю, что вы позволяете пользователю выбрать адрес из его списка адресов (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
}

Вам нужно выбрать решение в соответствии с подходом базы данных, который вы хотите использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...