У меня есть отношения друг к другу между двумя таблицами, но внешний ключ находится на том, который мне не нужно сопоставлять, администратор базы данных сделал это в пользу будущих изменений.OneToOne двунаправленное сопоставление внешнего ключа автозаполнения
Предположим, у нас есть Пользователь и Адрес, сегодня каждый пользователь имеет только один адрес, и он будет отображаться таким образом, но DBA верят, что в будущем это может быть сопоставление от одного до многих, поэтому внешний ключ пользователя по адресу, но приложение имеет экземпляры пользователей, что важно для автоматического выбора адреса.
Мы сделали это правильно, следующим образом:
@Entity
@Table(name = "user")
class User {
@Id
@Column(name = "user_id")
private Long id;
//...
@OneToOne(cascade = CascadeType.MERGE, mappedBy = "user")
private Address address; // this attribute is crucial
}
@Entity
@Table(name = "address")
class Address {
@Id
@Column(name = "address_id")
private Long id;
@OneToOne
@JoinColumn(name = "user_id")
private User user; // this attribute is not needed for the business at all, but mappedBy requires it
//...
}
База данных:
-- SQL:
CREATE TABLE user
(
user_id INT NOT NULL,
-- ...
CONSTRAINT user_pk PRIMARY KEY (user_id)
);
CREATE TABLE address
(
address_id INT NOT NULL,
user_id INT NOT NULL,
-- ...
CONSTRAINT address_pk PRIMARY KEY (address_id),
CONSTRAINT address_user_id_fk FOREIGN KEY (user_id) REFERENCES user (user_id),
CONSTRAINT address_user_id_uk UNIQUE (user_id) -- it says it's a one to one relation for now, if in the future it won't be anymore, just remove this constraint
);
Проблема заключается в том, когда сохранить экземпляр пользователя с новым экземпляром адреса, атрибут пользователя адреса является null
, поэтому я ожидал, что Hibernate был достаточно умен, чтобы установить его значение из экземпляра пользователя, из которого он исходит.
Я искал решение в течение нескольких дней, но до сих пор не нашел, как это решить, тем временем я устанавливаю значение вручную, но я ожидаю, что мне не нужно это делать.
Я вижу, мне было интересно, что Hibernate может быть достаточно умным, чтобы сделать это для меня, но это решение лучше, чем устанавливать пользователю каждый фрагмент кода, который создает адрес. –