ShaggyInjun
ShaggyInjun

Reputation: 2973

Mapping both the key and the object in JPA

I am looking at somebody else's code and I have never seen both the key and the object mapped for a one to one mapping, is doing something like this okay ?

@Entity
@Table(name = "PROJECT_POINTER")
public class ProjectPointerEntity {

    private static Logger LOG = LoggerFactory.getLogger(ProjectPointerEntity.class);

    @Id
    @SequenceGenerator(name = "seqGen", sequenceName = "PROJECT_POINTER_SEQ", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seqGen")
    @Column(name = "PROJECT_POINTER_ID")
    private Long projectPointerId;


    @Column(name = "HOSTING_LOCATION_KEY")
    private String hostingLocationKey;


    @OneToOne(fetch = FetchType.EAGER, optional = false)
    @JoinColumn(name = "HOSTING_LOCATION_KEY", insertable = false, updatable = false)
    private HostingLocationEntity hostingLocation = new HostingLocationEntity();


    public String getHostingLocationKey() {
        return hostingLocationKey;
    }

    public void setHostingLocationKey(String hostingLocationKey) {
        this.hostingLocationKey = hostingLocationKey;
    }

    public HostingLocationEntity getHostingLocation() {
        return hostingLocation;
    }

    public void setHostingLocation(HostingLocationEntity hostingLocation) {
        this.hostingLocation = hostingLocation;
    }

}

Upvotes: 3

Views: 2326

Answers (1)

Chris
Chris

Reputation: 21165

This is allowed and has both benefits and consequences. You will notice that in the second mapping, the OneToOne has a JoinColumn annotation that marks the field as insertable = false, updatable = false - this essentially makes the OneToOne mapping read only. So to change the field/relationship, the hostingLocationKey needs to be set using the ID value from the to-be-referenced HostingLocationEntity instance. The OneToOne mapping should still be updated as well to keep the object model insync with the database. The draw back, other than maintaining both attributes, is that the ID value to use must be preset - JPA will not assign an ID to HostingLocationEntity if it is new and then automatically update the foreign key field because the foreign key mapping is not updatable/insertable.

One of the benefits is that there is an attribute directly to the HOSTING_LOCATION_KEY foreign key, allowing the application to use it in queries directly rather than risk a table join by using "projectPointerEntity.hostingLocation.id" in queries, or having to fetch the hostingLocation to just get the id. The last benefit is negated by the mapping being marked as Eager though, meaning it is always fetched anyway. So unless your application makes use of the hostingLocationKey in queries where the JPA provider would force a table join otherwise, it might be redundant as the application can access it from the referenced hostingLocation anyway.

Upvotes: 3

Related Questions