mconner
mconner

Reputation: 1556

How to define a Hibernate OneToOne unidirectional mapping in Parent where the FK column is in the child?

Background: I'm in the process of upgrading to Hibernate 6.1.4 (from 5.3.x) and have run into problems with OneToOne bidirectional mappings (which appears to be a bug, and I've written up). I'm looking for a workaround that doesn't require changing the schema and am considering making the mapping unidirectional but have run into an issue.

Here's a simplified version of the starting point:

@Entity
@Table(name = "PARENT_T")
public class Parent {
    @Id
    @Column(name = "PARENT_PK")
    private Integer id;

    @OneToOne(targetEntity = Child.class, mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Child child;

    // getters and setters...
}


@Entity
@Table(name = "PARENT_T")
public class Child {
    @Id
    @Column(name = "CHILD_PK")
    private Integer id;

    @OneToOne(targetEntity = Parent.class, fetch = FetchType.EAGER)
    @JoinColumn(name = "PARENT_FK", nullable = false)
    private Parent parent;

    // getters and setters...
}

So, I would like to remove the Child-to-Parent mapping, and just map the attribute:

    @Column(name = "PARENT_FK", nullable = false)
    private Long parentFK;

However, this means that the mappedBy = "parent" in the Parent is no longer valid. I can add a JoinColumn annotation, but per the docs, the JoinColumn name is in the source entity (here, Parent):

The name of the foreign key column. The table in which it is found depends upon the context.

If the join is for a OneToOne or ManyToOne mapping using a foreign key mapping strategy, the foreign key column is in the table of the source entity or embeddable.

I saw a suggestion to use a OneToMany mapping, since:

If the join is for a unidirectional OneToMany mapping using a foreign key mapping strategy, the foreign key is in the table of the target entity.

... and then treat it as a One-to-One. However, this seems like a kludge.

So: Is there a way to map a OneToOne relationship where the foreign key column lies with the target entity (here: Child), rather than the source (here: Parent)?

Conceptually, I'm just looking for a table equivalent of mappedBy in the annotation, Something like: @OneToOne(targetEntity = Child.class, mappedByColumn = "PARENT_FK", cascade = CascadeType.ALL, fetch = FetchType.LAZY)

Thanks!

Upvotes: 2

Views: 879

Answers (1)

Christian Beikov
Christian Beikov

Reputation: 16400

Try this mapping here:

@MapsId
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "PARENT_PK", referencedColumnName = "PARENT_FK")
private Child child;

Upvotes: -2

Related Questions