# Hibernate changes outer to inner join when @EntityGraph and @Id

**URL:** https://discourse.hibernate.org/t/hibernate-changes-outer-to-inner-join-when-entitygraph-and-id/7902
**Category:** Hibernate ORM
**Created:** [June 30, 2023, 2:04pm UTC](https://discourse.hibernate.org/t/hibernate-changes-outer-to-inner-join-when-entitygraph-and-id/7902 "2023-06-30T14:04:02Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Konrad\_Wajs](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/konrad_wajs/32/2540_2.png) [@Konrad\_Wajs](https://discourse.hibernate.org/u/Konrad_Wajs)
#### Post date: [June 30, 2023, 2:04pm UTC](https://discourse.hibernate.org/t/hibernate-changes-outer-to-inner-join-when-entitygraph-and-id/7902/1 "2023-06-30T14:04:02Z")

</div>

I’m using @EntityGraph to load some attributes eagerly. But sth has broken after update from 5.x to 6.x.

Let say we have a human who can have multiple houses:

```auto
public class Human {
    @Id
    @Column(name = "ID", nullable = false, updatable = false, precision = 20)
    @GeneratedValue
    private BigInteger id;

    @EqualsAndHashCode.Exclude
    @ToString.Exclude
    @OneToMany(mappedBy = "human", cascade = CascadeType.ALL)
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Collection<House> houses;
}

```

When search for him, by id, EntityGraph can load something eagerly:

```auto
@EntityGraph(attributePaths = { "houses.address" })
@Query ("SELECT h FROM Human h WHERE h.id IN ?1")
Human findByIdEagerHouseAddresses(Integer id);

```

this will create sql with left (outer by default) joins:

```auto
select h1_0.id,h2_0.human_fk,h2_0.address_fk,a1_0.id 
from human h1_0 
left join house h2_0 on h1_0.id=h2_0.human_fk
left join address a1_0 on a1_0.id=h2_0.address_fk where h1_0.id in (?)

```

This is ok, I will get my human, even if it has no house.

**But if address field in house will have annotation @Id, outer join will change to “inner”:**

```auto
@Entity
public class House {
    @Id
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "human_fk", nullable = false, updatable = false)
    private Human human;

    @Id // THIS ANNOTATION WAS ADDED
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "address_fk", nullable = false, updatable = false)
    private Address address;
}

```

```auto
select h1_0.id,h2_0.human_fk,h2_0.address_fk,a1_0.id 
from human h1_0 
left join house h2_0 on h1_0.id=h2_0.human_fk 
join address a1_0 on a1_0.id=h2_0.address_fk where h1_0.id in (?)

```

If a human does not have a house, query returns nothing, because of join (which is inner), which seems like a bug.

Is it really a bug? or a feature? I have checked this on latest 3.1.1 spring boot.

---

<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: [July 14, 2023, 12:56pm UTC](https://discourse.hibernate.org/t/hibernate-changes-outer-to-inner-join-when-entitygraph-and-id/7902/2 "2023-07-14T12:56:24Z")

</div>

This can only be a problem if you don’t have a foreign key constraint on the database. In that case, you will have to tell Hibernate that by annotating `@NotFound(IGNORE)`, but you really shouldn’t model your database this way.  
Which Hibernate version are you using?

---

<div class="post-metadata">

### Author: ![Konrad\_Wajs](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/konrad_wajs/32/2540_2.png) [@Konrad\_Wajs](https://discourse.hibernate.org/u/Konrad_Wajs)
#### Post date: [July 14, 2023, 9:38pm UTC](https://discourse.hibernate.org/t/hibernate-changes-outer-to-inner-join-when-entitygraph-and-id/7902/3 "2023-07-14T21:38:18Z")

</div>

Thank you for answer!

At first glance, I thought so too, but the inner join propagates from the address to the whole query. So, when we have one record in the ‘human’ table, with no associated house (which implies that the ‘address’ table is empty),

SELECT \* FROM human LEFT OUTER JOIN house → returns 1 row  
SELECT \* FROM human LEFT OUTER JOIN house INNER JOIN address → returns 0 rows

There can be a constraint between the ‘address’ and ‘house’ tables, but it’s completely okay for a human to be “homeless”.

I prepared [test case](https://github.com/bioc-wajskonr/EntityGraph-hibernate-templates/blob/main/orm/hibernate-orm-6/src/test/java/demo/EntityGraphTest.java) in github (based on hibernate template) without spring.

Regarding versions:

- Hibernate 6.0.0 - 6.1.5 → combination of @EntityGraph and @Id cause the final query to omit completely left outer join for entityGraphs attributes
- Hibernate 6.1.6 - 6.2.6 (latest 6.2.x) → entityGraph attributes are there again, but query has inner join instead of outer join

---

<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: [July 17, 2023, 8:24am UTC](https://discourse.hibernate.org/t/hibernate-changes-outer-to-inner-join-when-entitygraph-and-id/7902/4 "2023-07-17T08:24:52Z")

</div>

Thanks for your test case template. Would be so kind and [create a JIRA issue](https://hibernate.atlassian.net) for this, linking to this discussion and the test case project you created?

---

<div class="post-metadata">

### Author: ![Konrad\_Wajs](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/konrad_wajs/32/2540_2.png) [@Konrad\_Wajs](https://discourse.hibernate.org/u/Konrad_Wajs)
#### Post date: [July 22, 2023, 4:56pm UTC](https://discourse.hibernate.org/t/hibernate-changes-outer-to-inner-join-when-entitygraph-and-id/7902/5 "2023-07-22T16:56:21Z")

</div>

I’ve already created a ticket, but no one seems to be interested in it. ☹  
Perhaps I wasn’t clear enough in my description, or maybe the description is too extensive?  
[https://hibernate.atlassian.net/jira/software/c/projects/HHH/issues/HHH-16885](https://hibernate.atlassian.net/jira/software/c/projects/HHH/issues/HHH-16885)

Is there any way I can make this ticket more appealing?

From our perspective, it’s a blocker, as we are heavily dependent on entitygraphs. Due to bugs in Hibernate version 6 and above, we’re unable to upgrade to Spring Boot 3.

---

<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: [July 24, 2023, 10:26am UTC](https://discourse.hibernate.org/t/hibernate-changes-outer-to-inner-join-when-entitygraph-and-id/7902/6 "2023-07-24T10:26:06Z")

</div>

If you can’t wait until the Hibernate Team finds the time to fix this bug, you will have to fix it yourself. It’s an open source project after all and everyone has to pick their battles.
