I have a relationship one-to-one between two tables, but the foreign key is on the one I don't need to map, the DBA did this in favor of future changes.
Let's imagine we have User and Address, today every user has only one address, and it will be mapped this way, but DBA believe in the future it could be a one to many mapping, so the foreign key of user is on the address, but the application have instances of users, which is important to fetch address automatically.
We did it right, as follow:
@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
//...
}
Database:
-- 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
);
The problem is when save a instance of user with a new instance of address, the user's attribute of address is null
, so I was expecting Hibernate was smart enough to set it the value from the user's instance it comes from.
I'd been looking for a solution for a couple of days, but still didn't find how to solve this, meanwhile I'm setting the value manually, but I expect I don't need to do so.