У меня есть отношение один к одному между двумя таблицами, но внешний ключ находится на той, которую мне не нужно сопоставлять, администратор базы данных сделал это в пользу будущих изменений.
Давайте представим, что у нас есть пользователь и адрес, сегодня у каждого пользователя есть только один адрес, и он будет отображаться таким образом, но администраторы баз данных считают, что в будущем это может быть сопоставление один ко многим, поэтому внешний ключ пользователя находится на адресе, но в приложении есть экземпляры пользователей, что важно для автоматического получения адреса.
Мы сделали это правильно, как показано ниже:
@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 достаточно умен, чтобы установить значение из экземпляра пользователя, из которого он исходит.
Я искал решение пару дней, но так и не нашел, как это решить, пока что я устанавливаю значение вручную, но я ожидаю, что мне это не нужно.