one-to-one causes redundant select query


This mapping causes 2 instead of the expected 1 query to retrieve a Customer and its Address from the db:

select * from Customer customer0_ left outer join Address address1_ on where
select * from Customer customer0_ left outer join Address address1_ on where customer0_.address_id=?

Changing the mapping to a LAZY fetch type:

@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Address address = new Address();

Causes 3 select queries instead of the expected 2 queries to retrieve a Customer (and its Address) from the db:

select * from Customer customer0_ where
select * from Address address0_ left outer join Customer customer1_ on where
select * from Customer customer0_ where customer0_.address_id=?

The third select is superfluous because the relationship is already completely known: you already have the customer, so why not just set it on the address entity?

Making the address field in Customer a @ManyToOne doesn't make a difference.

Making the customer field in Address a @OneToMany does remove the extra select, but forces our model to change the relationship from Customer to List<Customer> where we know there'll be only 1 element.

Apparently Hibernate can figure out the reverse relationship with a @ManyToOne - @OneToMany without the need for additional queries, can't this be extended to @OneToOne bidirectional relationships as well?




Vlad Mihalcea
March 28, 2018, 12:43 PM

Applied PR upstream.

Giovanni Lovato
June 22, 2018, 9:15 AM

I'm still experiencing this in 5.2.17, 5.3.0 and 5.3.1 with this test:

It generates three queries, while I would expect one single query i.e.

Christian Beikov
June 22, 2018, 10:45 AM

Not sure if the use of the JPA Criteria API plays a role here, but as you can see in the test, your case should be covered:
If you could create PR against hibernate-orm with the testcase I could take a look.

Giovanni Lovato
June 22, 2018, 11:14 AM

I looked at the tests and definitely the use of the Criteria API plays a role, as it defaults to `SELECT` fetch. Still it's not clear to me why this is the default, as a `JOIN` would be more performant, AFAIK.

Gail Badner
August 26, 2018, 3:47 AM

Fixed in 5.1 branch as well.


Christian Beikov



Fix versions




Suitable for new contributors


Requires Release Note





Affects versions