В моем заявлении у меня есть тендер.Как работает операция слияния с отношениями «один ко многим» - JPA
@Entity
@Table(name = "tender")
public class Tender {
@Id
@Column(name = "tender_id", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "name")
private String name;
@Column(name = "description")
private String description;
@OneToMany(mappedBy="tender", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JsonIgnoreProperties("tender")
private List<TenderAddress> addresses;
// constructors and getters and setters
// I am showing the setter for Address since it is customized for my requirement
public void setAddresses(List<TenderAddress> addresses) {
this.addresses = addresses;
for (TenderAddress tenderAddress : addresses) {
tenderAddress.setTender(this);
}
}
}
Объект My TenderAddress
выглядит следующим образом.
@Entity
@Table(name = "tender_address")
public class TenderAddress {
@Id
@Column(name = "id", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="tender_id")
@JsonIgnoreProperties("addresses")
private Tender tender;
@Column(name = "address", nullable = false)
private String address;
// constructors
//getters and setters
}
Все работало нормально, пока я не начал тестирование операции обновления.
Это мой метод обновления.
@Transactional
public Tender updateTender(Tender tender) {
Tender t = entityManager.find(Tender.class, tender.getId());
t.setName(tender.getName());
t.setDescription(tender.getDescription());
t.setAddresses(tender.getAddresses());
entityManager.merge(t);
entityManager.flush();
return findById(t.getId());
}
имя и описание обновляются в порядке. То, что я подумал о том, как будут обновляться адреса, - это отредактировать текущую запись в соответствующей таблице базы данных. Но произошло то, что он вставил новую запись в таблицу без редактирования уже существующей записи. На самом деле, я думал, что JPA заботится об этом.
Итак, теперь мой вопрос: я должен явно объединить таблицу адресов при слиянии тендерной таблицы? Если да, то как это должно быть сделано?
Когда вы вызываете 'updateTender', откуда берутся записи в списке' tender.addresses'? У них есть свои исходные идентификаторы?Если нет, JPA не может знать, что они должны рассматриваться как существующие объекты. – crizzis
@crizzis эти адреса заданы в классе контроллера. Это в DAO. Я не устанавливаю идентификаторы для адресных объектов. Но идентификатор тендера для них устанавливается с использованием метода setter, когда я вызываю 't.setAddresses (tender.getAddresses)'. Должен ли я устанавливать идентификаторы для объектов Address? – vigamage
Вы должны просто не потерять информацию об идентификаторах существующих адресов, даже если вы представляете их в представлении в отдельном состоянии. Я не знаю, какую конкретную технологию просмотра вы используете, но если это веб-приложение, вы можете, например, сохранить свои идентификаторы в скрытых полях ввода. Кроме того, я настоятельно рекомендую добавить 'orphanRemoval = true' в аннотацию' @ OneToMany' – crizzis