Переход от многих ко многим со ссылкой на существующую запись

#hibernate #jpa #many-to-many

#переход в спящий режим #jpa #многие ко многим

Вопрос:

У меня есть отношение многие ко многим между двумя объектами: Item и ItemCategory

В элементе класса

 @ManyToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE})
@JoinTable(
        name="LINK_ITEM_CATEGORY",
        joinColumns={@JoinColumn(name="ITEM_ID")},
        inverseJoinColumns={@JoinColumn(name="CATEGORY_ID")}
        )
private Set<ItemCategory> associatedCategories = new HashSet<ItemCategory>();   
  

В классе ItemCategory

 @Column(name="NAME")
private String name;

@ManyToMany(mappedBy="associatedCategories")
private Collection<Item> comprisesExpenditure = new ArrayList<Item>();
  

Всякий раз, когда я пытаюсь сохранить элемент, категории, добавленные в Set associatedCategories , сохраняются, даже если в базе данных существует категория по тому же принципу name . Есть ли какой-нибудь способ для hibernate выполнить поиск категорий на основе name и создать ссылку с существующей, вместо создания новой категории и связывания элемента с новой.

Ответ №1:

Чтобы это работало должным образом, вы должны правильно реализовать методы hashCode и equals. Без этого HashSet может вести себя непредсказуемо.

Комментарии:

1. Да, я реализовал их, но не включил их выше. Но это гарантирует только уникальную категорию, связанную с конкретным расходом. Однако я не могу повторно использовать какую-либо категорию в нескольких расходах.

Ответ №2:

Нет. Поскольку name не является идентификатором категории, у вас может быть несколько категорий с одинаковым именем. Вы могли бы добавить уникальное ограничение, но Hibernate не может волшебным образом знать, что новая категория, которую вы добавляете в набор, на самом деле должна быть существующей категорией с тем же именем.

При создании категорий и добавлении их в набор следует выполнить поиск категории с таким же именем и, если она существует, поместить эту существующую категорию в набор вместо новой.

Комментарии:

1. Это сработало. Я искал категории и, если нашел, заменил их в наборе, связанном с элементом. После этого элемент и категории были корректно связаны с новыми созданными категориями, если они еще не существовали.