Это двунаправленное отношение, т.е. объектам обеих категорий известно, какому объекту они назначены. Вы можете go показанным способом и вручную синхронизировать отношения. Однако это довольно сложно и подвержено ошибкам.
Более простой и понятный способ - создать метод для каждого класса для синхронизации при добавлении нового партнера по отношениям. Влад Михалча очень четко описывает этот подход в своей статье о @ManyToMany
отношениях . Кроме того, вы можете найти его в этой статье о каскадировании и синхронизации .
Здесь его код адаптирован для вашего случая использования:
@Entity(name = "Category")
@Table(name = "category")
public class Category {
@Id
@GeneratedValue
private Long id;
private String title;
public Category() {}
public Category(String title) {
this.title = title;
}
@ManyToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
@JoinTable(name = "category_item",
joinColumns = @JoinColumn(name = "category_id"),
inverseJoinColumns = @JoinColumn(name = "item_id")
)
private Set<Item> items = new HashSet<>();
//Getters and setters ommitted for brevity
public void addItem(Item item) {
items.add(item);
item.getCategories().add(this);
}
public void removeItem(Item item) {
items.remove(item);
item.getCategories().remove(this);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Category)) return false;
return id != null && id.equals(((Category) o).getId());
}
@Override
public int hashCode() {
return 31;
}
}
@Entity(name = "Item")
@Table(name = "item")
public class Item {
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToMany(mappedBy = "items")
private Set<Category> categories = new HashSet<>();
public Item() {}
public Item(String name) {
this.name = name;
}
//Getters and setters ommitted for brevity
private void addCategory(Category category) {
categories.add(category);
category.getItems().add(this);
}
public void removeCategory(Category category) {
categories.remove(category);
category.getItems().remove(this);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Item)) return false;
return id != null && id.equals(((Item) o).getId());
}
@Override
public int hashCode() {
return 41;
}
}
Кстати: автоматическая генерация идентификаторы, если они не являются естественными, также менее подвержены ошибкам.