Uploaded image for project: 'Hibernate ORM'
  1. HHH-3930

one-to-one causes redundant select query

    Details

      Description

      @Entity
      public class Address {
          @Id
          @GeneratedValue(strategy = GenerationType.AUTO)
          private Long id;
      
          @OneToOne(mappedBy = "address")
          private Customer customer;
      }
      
      @Entity
      public class Customer {
          @Id
          @GeneratedValue(strategy = GenerationType.AUTO)
          private Long id;
      
          @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
          private Address address = new Address();
      
          public Long getId() {
      	return id;
          }
      
          public Address getAddress() {
      	return address;
          }
      }
      

      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 customer0_.address_id=address1_.id where customer0_.id=?
      select * from Customer customer0_ left outer join Address address1_ on customer0_.address_id=address1_.id 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 customer0_.id=?
      select * from Address address0_ left outer join Customer customer1_ on address0_.id=customer1_.address_id where address0_.id=?
      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?

        Attachments

          Issue links

            Activity

              People

              • Votes:
                17 Vote for this issue
                Watchers:
                23 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: