Your DB schema is a bit unusual. With your schema design, you'll always need two queries to add wallet to user:
-- let's assume user's id is 1
insert into users_wallet(id, user_id, currency, value) values (1, 1, 'EUR', 2.0);
update user set wallet_id = 1 where id = 1;
Common approach is to have only one foreign key, let's say in child entity. For example, a user can have a wallet. In that case, you can add the foreign key user_id
in users_wallet
table. That way when you want to add wallet to a user, you just add wallet to a user:
-- again let's assume user's id is 1
insert into users_wallet(user_id, currency, value) values (1, 'EUR', 2.0);
So, your DB schema could then look like:
CREATE TABLE users_wallet
(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
user_id INT UNSIGNED,
currency VARCHAR(3),
value DOUBLE,
PRIMARY KEY (id)
);
CREATE TABLE users
(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
FOREIGN KEY (wallet_id) REFERENCES users_wallet (id)
);
With such schema, you would have following mappings:
class User {
// ...
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL,
fetch = FetchType.LAZY, optional = false)
private UserWallet userWallet;
}
class UserWallet {
// ...
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
}
But you can improve your DB design even further. Since there can only be one wallet per user, you don't really need both id
as primary key and user_id
as foreign key. You could just use user_id
as primary key, which would mirror primary key of user
table. In that case mapping for UserWallet
class is following:
class UserWallet {
// ...
@OneToOne(fetch = FetchType.LAZY)
@MapsId
private User user;
}