简体   繁体   中英

JPA 2: Determine an entitys id by looking up JoinColumn - Shared primary key in one-to-one relation

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!

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). Eg Add MapsId to the Client not Preferences as above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM