# Mapping unidirectional one-to-one relations correctly

**URL:** <https://discourse.hibernate.org/t/mapping-unidirectional-one-to-one-relations-correctly/10109>\
**Category:** Hibernate ORM\
**Created:** [August 9, 2024, 1:15pm UTC](https://discourse.hibernate.org/t/mapping-unidirectional-one-to-one-relations-correctly/10109 "2024-08-09T13:15:58Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![1dEraNCeSIv0](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/1derancesiv0/32/3411_2.png) [@1dEraNCeSIv0](https://discourse.hibernate.org/u/1dEraNCeSIv0)\
**Post date:** [August 9, 2024, 1:15pm UTC](https://discourse.hibernate.org/t/mapping-unidirectional-one-to-one-relations-correctly/10109/1 "2024-08-09T13:15:58Z")

</div>

I have what I thought was a pretty basic database schema and yet it seems I cannot model it correctly in Hibernate.

I’ve searched this forum and found an old thread discussing something similar, 0 answers.  
I searched the web and hibernate’s issue tracker, I only found out what does not work but no solution.

So any help would be appreciated.

My database-schema, witten as a postgresql flyway script:

```sql
create table parent (
    id uuid primary key
)

create table child (
    id uuid primary key,
    parent_id uuid not null reference parent (id)
)

```

My current approach as entities, which do not quite work as they are:

```java
@Entity
class Parent {
    @Id
    private UUID id;
    @OneToOne(cascade = ALL)
    private Child child;
}

@Entity
class Child {
    @Id
    private UUID id;
    private UUID parentId;
}

```

The issue is saving a parent with a child does not work: Hibernate attempts to save the `child` before it saves the `parent`, leading to my db throwing an exception, as it should.

Now, I know one, maybe 2 ways to convince hibernate to save the parent first:

1. I could replace the field `child.parentId` with `parent.childId`.

- Pros: Java-model can stay as-is (minor changes to mapping annotations perhaps)
- Cons: I have use cases where other entities want to join the child by parentId. In this version I would need to join `other entity -> parent -> child` which seems quite uncessary

1. model the relation in java as a bidirectional relation

- Pros: I can join `other entity -> child` directly
- Cons: Bidirectional relations are annoying to manage. I have 0 actual use cases for the field `child.parent` but a bunch of extra work for the sole purpose of convincing Hibernate to save the `parent`, `child` entities in the correct order.

So I’m looking for a way to do this correctly, ideally without a) turning the relation bidirectional and b) moving the foreign key from the `child` to the `parent` table in the db. Alternatively, an explanation for why it does not work / is a bad idea would be appreciated also.

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [August 9, 2024, 3:26pm UTC](https://discourse.hibernate.org/t/mapping-unidirectional-one-to-one-relations-correctly/10109/2 "2024-08-09T15:26:57Z")

</div>

The `Parent` entity does not have a foreign key column, so you must use `mappedBy`. Either referring to an association:

```java
@Entity
class Parent {
    @Id
    private UUID id;
    @OneToOne(mappedBy = "parent", cascade = ALL)
    private Child child;
}

@Entity
class Child {
    @Id
    private UUID id;
    @OneToOne(cascade = ALL)
    @JoinColumn(name = "parent_id")
    private Parent parent;
}

```

Or to a field that maps the id:

```java
@Entity
class Parent {
    @Id
    private UUID id;
    @OneToOne(mappedBy = "parentId", cascade = ALL)
    private Child child;
}

@Entity
class Child {
    @Id
    private UUID id;
    private UUID parentId;
}

```

Note though that for this mapping to be 100% correct, you would have to mark the `parent_id` column as unique.

---

<div class="post-metadata">

**Author:** ![1dEraNCeSIv0](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/1derancesiv0/32/3411_2.png) [@1dEraNCeSIv0](https://discourse.hibernate.org/u/1dEraNCeSIv0)\
**Post date:** [August 9, 2024, 4:06pm UTC](https://discourse.hibernate.org/t/mapping-unidirectional-one-to-one-relations-correctly/10109/3 "2024-08-09T16:06:19Z")

</div>

Thanks for the quick response 🙂

Something in the style of the second option is what I am after. And in fact for some unidirectional `@OneToMany` associations I have your proposal is exactly how I do it and it works.  
However, when I try to use `mappedBy = "<foreign key field name>"` with `@OneToOne` associations I always end up with this exception:

> Association ‘com.example.onetoone.Parent.child’ is ‘mappedBy’ a property named ‘parentId’ of the target entity type ‘com.example.onetoone.Child’ which is not a ‘@OneToOne’ or ‘@ManyToOne’ association

I had understood the exception message to mean, basically, “you cannot just reference a field, you need to make it bidirectional and reference the other side”. But I would like to avoid making the relation bidirectional, so I’ve been looking for other solutions.  
That said, maybe I’m just not doing it right? If there is a way to make it work via `mappedBy` referencing the foreign key in the `Child` table then that’d be great 🙂

> **My current classes / schema**
>
> Entities:
> 
> ```java
> @Entity
> @NoArgsConstructor
> @AllArgsConstructor
> class Parent {
> @Id
> private UUID id;
> 
> @OneToOne(mappedBy = "parentId", cascade = CascadeType.ALL)
> private Child child;
> }
> 
> @Entity
> @NoArgsConstructor
> @AllArgsConstructor
> class Child {
> @Id
> private UUID id;
> 
> private UUID parentId;
> }
> 
> ```
> 
> DB:
> 
> ```sql
> -- h2 dialect as the sample project I threw together to run the simplified example uses h2
> create table parent
> (
> id uuid primary key
> );
> 
> create table child
> (
> id uuid primary key,
> parent_id uuid unique not null,
> foreign key (parent_id) references parent (id)
> );
> 
> ```
> 
> Testing setup:
> 
> ```java
> @SpringBootTest
> class OneToOneApplicationTests {
> 
> @Autowired
> private EntityManager entityManager;
> 
> @Test
> @Transactional
> void contextLoads() {
> Session session = entityManager.unwrap(Session.class);
> UUID parentId = randomUUID();
> UUID childId = randomUUID();
> session.persist(new Parent(parentId, new Child(childId, parentId)));
> 
> session.flush(); // this is where it errors 
> }
> 
> }
> 
> ```

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [August 12, 2024, 3:07pm UTC](https://discourse.hibernate.org/t/mapping-unidirectional-one-to-one-relations-correctly/10109/4 "2024-08-12T15:07:26Z")

</div>

This was fixed in recent Hibernate ORM version. Please upgrade to the latest version e.g. 6.6.0.Final

---

<div class="post-metadata">

**Author:** ![1dEraNCeSIv0](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/1derancesiv0/32/3411_2.png) [@1dEraNCeSIv0](https://discourse.hibernate.org/u/1dEraNCeSIv0)\
**Post date:** [August 12, 2024, 5:35pm UTC](https://discourse.hibernate.org/t/mapping-unidirectional-one-to-one-relations-correctly/10109/5 "2024-08-12T17:35:45Z")

</div>

Was really excited to hear that, just got around to try it out but sadly no changes ☹

Did the whole `gradle clean`, clean rebuild in the IDE, check the dependency graph really shows 6.6.0.Final but all to no use. Even on 6.6.0.Final I still get the above error when attempting to point `OneToOne.mappedBy` to a foreign key that is not annotated with `@OneToOne` ifself (because it’s unidirectional).

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [August 13, 2024, 12:19pm UTC](https://discourse.hibernate.org/t/mapping-unidirectional-one-to-one-relations-correctly/10109/6 "2024-08-13T12:19:54Z")

</div>

Well, seems I mixed that up with something else. It works for `@OneToMany` though.  
You should be able to annotate it like this though:

```auto
@Entity
class Parent {
    @Id
    private UUID id;
    @OneToOne(cascade = ALL)
    @JoinColumn(name = "id", referenceColumnName = "parent_id", insertable = false, updatable = false)
    private Child child;
}

@Entity
class Child {
    @Id
    private UUID id;
    private UUID parentId;
}

```

---

<div class="post-metadata">

**Author:** ![1dEraNCeSIv0](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/1derancesiv0/32/3411_2.png) [@1dEraNCeSIv0](https://discourse.hibernate.org/u/1dEraNCeSIv0)\
**Post date:** [August 13, 2024, 8:55pm UTC](https://discourse.hibernate.org/t/mapping-unidirectional-one-to-one-relations-correctly/10109/7 "2024-08-13T20:55:57Z")

</div>

Doing it via `@JoinColumn` is one more option that looks like it should work yet does not ☹ Instead hibernate attemps to save the child first again. Approximately this works for `@OneToMany` though.

The fact that all of this works with `@OneToMany` always makes me think it should work with `@OneToOne`, somehow, and I’ve just not found the right way to do it yet…

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [August 14, 2024, 10:02am UTC](https://discourse.hibernate.org/t/mapping-unidirectional-one-to-one-relations-correctly/10109/8 "2024-08-14T10:02:01Z")

</div>

Please try to create a reproducer with our [test case template](https://github.com/hibernate/hibernate-test-case-templates/blob/master/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java) and if you are able to reproduce the issue, create a bug ticket in our [issue tracker](https://hibernate.atlassian.net) and attach that reproducer.

The last thing that you could try is also annotate `@MapsId` on the `@OneToOne`

---

<div class="post-metadata">

**Author:** ![1dEraNCeSIv0](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/1derancesiv0/32/3411_2.png) [@1dEraNCeSIv0](https://discourse.hibernate.org/u/1dEraNCeSIv0)\
**Post date:** [August 15, 2024, 8:52pm UTC](https://discourse.hibernate.org/t/mapping-unidirectional-one-to-one-relations-correctly/10109/9 "2024-08-15T20:52:03Z")

</div>

Tried `@MapsId` with no luck either. But I’ve finally taken the time to build a reproducer using your template and opened [a bug issue](https://hibernate.atlassian.net/browse/HHH-18495).

Thanks for your time and patience 🙂

---

<div class="post-metadata">

**Author:** ![stdh](https://avatars.discourse-cdn.com/v4/letter/s/8edcca/32.png) [@stdh](https://discourse.hibernate.org/u/stdh)\
**Post date:** [May 10, 2026, 12:30am UTC](https://discourse.hibernate.org/t/mapping-unidirectional-one-to-one-relations-correctly/10109/10 "2026-05-10T00:30:50Z")

</div>

I too need to model a unidirectional one-to-one relation and I can’t use mappedBy (details [here](https://discourse.hibernate.org/t/onetoone-relation-mappedby-any/12235)). Using @JoinColumn didn’t work for me either. But I must admit I’m still on 6.6 – is there anything in newer releases that’s relevant here, perhaps?

One way to handle this in my particular case would be to use a @OneToMany-relation so I can use mappedBy, and then pretend it’s OneToOne through getter/setter. Continuing the example:

```java
@Entity
class Parent {
    @OneToMany(mappedBy = "parent", cascade = ALL)
    private Set<Child> children = new HashSet<Child>();

    public Child getChild() {
        for (Child ch : children) {
            return ch;
        }
        return null;
    }

    public void setChild(Child ch) {
        children = Set.of(ch);
    }
}

```

Not too elegant, but it’ll work I presume. Anybody know of a better way?
