I am trying to do something that seems simple but maybe not.
I have a credential table that just has a password hash.
I have a user table with user data.
Every user must have one credential, so one-to-one.
I only need the credential record for creating a user and for logging in. Seemed reasonable to have the credential reuse the primary key of the user. So I set them up like this:
Code:
@Entity
public class Credential {
@Id
private Long id;
@MapsId
@OneToOne( optional = false ) // I don't care if this is lazy loaded or not
@JoinColumn( name = "user_id" )
private User user;
...
}
@Entity
public class User {
@Id
@GeneratedValue
private Long id;
@OneToOne( optional=false, mappedBy="user", cascade = CascadeType.ALL, fetch = FetchType.LAZY )
private Credential credential;
...
public void setPassword( String password ) {
credential = Credentials.createFor( this, password );
}
The #setPassword method essential created a new credential with a hash of the pasword and sets the credential.setUser() to this.
Okay, so now when I persist User can you guess what happens? Right, I get a data integrity exception on inserting credential. That's because, yup, the user.id is set properly but there is no row yet in the user table. If I make credential optional=true it mysteriously works.
What am I doing wrong? They both require each other. So I'm not quite sure how to work this out.
Thanks in advance,
R.