Вы смешиваете две концепции: первичный ключ и внешний ключ.
Может быть только один PK, но FK просто означает "должен быть элемент с этим идентификатором в некоторой другой таблице". ФК не ограничивает уникальность.
[ПРАВКА] Ваша проблема в том, что вы смешиваете сущности. Как вы получили tag1
, который возвращается save()
?
Эта сущность должна быть той, которую вы получаете из Hibernate, а не результат new
. Даже если это выглядит безумно, вы должны сделать это в save()
:
session.save(tag);
return session.load(tag.getId());
Таким образом, вы получаете сущность, которой управляет Hibernate. Только когда объектом управляет Hibernate, Hibernate знает, когда ему нужно сохранить объект и когда он уже был сохранен.
Поэтому, когда вы делаете cat2.tags.add(tag1);
в своем примере выше, Hibernate думает: «О, я ничего не знаю об этом теге, он должен быть новым».
И снова пытается сохранить метку.