Несмотря на то, что называть целый Отдел только для ОДНОГО человека (это обычно группировка многих людей) - это, по крайней мере, неверное наименование, я полагаю, что вы действительно ищете связь OneToOne с общим PRIMARY KEY.
Лучшее решение (оптимальная память, скорость и обслуживание) @MapsId
:
@Getter
@Setter
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToOne(mappedBy = "person", fetch = FetchType.LAZY)
private Department department;
}
@Getter
@Setter
@Entity
public class Department {
@Id // Note no generation
private Long id;
private String name;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
@JoinColumn(name = "id", foreignKey = @ForeignKey(name = "department_belongs_to_person"))
private Person person;
}
Здесь Департамент владеет отношением (владение обычно означает, что в базе данных будет столбец с FK, но здесь они просто используют первичный ключ)и владеет FK, который привязывает свой PK к одному, сгенерированному Person.
Обратите внимание, что отношение является OneToOne, двунаправленным, с общим PK в качестве FK.Это считается наилучшей практикой, но имеет один небольшой недостаток, заключающийся в необходимости писать один метод получения.:)
Источники: https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/
Также - я настоятельно рекомендую потратить несколько дней на чтение сообщений на этом сайте и даже реализовать несколько из них, прежде чем создавать что-то большее, чем несколько таблиц.:)
РЕДАКТИРОВАТЬ
Я могу ошибаться (я уверен, что сейчас - смотрите комментарии), но, насколько мне известно, поддержание идентификаторов равноне то, что JPA указывает.В основном это может быть указано:
"Эй, вы, ребята (Person, Department), братья (OneToOne) и оба это знают (двунаправленный с mappedBy =" person "в сущности Person). Вы будете старше, браткоторый будет генерировать идентификаторы (Person имеет @GeneratedValue), и вы будете тем самым, у которого должно быть то же самое. Вы будете использовать эти поля (идентификаторы, одно сгенерированное, второе нет) для подключения (@PrimaryKeyJoinColumn). "
WhatЯ пытаюсь сказать, что если вы говорите «это связывает вас», это не значит, что они синхронизированы - вы должны это гарантировать.
Теперь о том, как это обеспечить - известен @MapsIdчтобы быть лучшим.
Если вы ищете другие подходы, есть также установка идентификатора вручную, чтобы он был таким же, как и другой, с #setDepartment (Department), где вы должны установить идентификатор отдела таким же, как и вызывающий абонент (но это толькоработает, если у указанного Person уже есть сгенерированный идентификатор, что в основном нарушает идею).
Другой известный мне вариант - использование стратегии стороннего генератора.
Person:
@Id
@GeneratedValue
private long id;
@OneToOne(mappedBy="person")
private Department department;
Отдел:
@Id
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign", parameters=@Parameter(name="property", value="person"))
private long id;
@OneToOne
@PrimaryKeyJoinColumn
private Person person;
Теперь - этот использует специфичные для hibernate аннотации и не является чистым JPA.