Reputation: 1414
I have two entity classes Client and Preferences in a bidirectional one-to-one relation. The entities should share the same primary key, which is generated programmatically by java.util.UUID.
Here is the minimalistic scenario:
@Entity
public class Client implements Serializable {
@Id
private String id;
@OneToOne(mappedBy = "client", casacade = CascadeType.PERSIST)
private Preferences preferences;
// ...
}
@Entity
public class Preferences implements Serializable {
@Id
@OneToOne
@JoinColumn
private Client client;
// ...
}
Everything works fine but I am disaffected because I can't find a clean way to provide a simple id field/property in Preferences.
In the scenario above I am forced to determine it by calling client.getId();
all the time
which looks quite messed up. So I was trying to figure out some alternatives. Here is what I found out so far:
Alternative A: Persist a basic value called id:
@Entity
public class Preferences implements Serializable {
@Id
@OneToOne
@JoinColumn
private Client client;
private String id;
public setClient (Client client) {
this.client = client;
id = client.getId();
}
// ...
}
The main problem with that solution is that it would store the same value twice...why then share a pk at all?!
Alternative B: Transient id:
@Entity
public class Preferences implements Serializable {
@Id
@OneToOne
@JoinColumn
private Client client;
@Transient
private String id;
@PostLoad
private void postLoad () {
id = client.getId();
}
public setClient (Client client) {
this.client = client;
id = client.getId();
}
// ...
}
Okay, here we don't save redundant data but Client must be fetched eagerly erverytime. That's the default behaviour in one-to-one relations but what if it would be better someday to have that client being fetched lazily? I don't like my options being restricted for no reason.
Is there a way to read the id given by Client directly out of that JoinColumn or should I use solution A/B?
I'm trying to stick to the spec, provider independent hints would be nice.
Thank you!
Upvotes: 1
Views: 262
Reputation: 496
Give this a try. It should grab the ID from the Client.
@Entity
public class Preferences implements Serializable {
@Id String id;
@OneToOne @MapsId
@JoinColumn
private Client client;
}
// ...
}
Furthermore, it might be worthwhile understanding which Object owns the relationship. It appears from your design that Preferences owns Client as Client (the non-owning side contains the mappedBy). Therefore it might be true in this case that the MapsId annotation is best suited to the non-owning (dependent object). E.g. Add MapsId to the Client not Preferences as above.
Upvotes: 1