title: Hibernate one-to-one lazy loading with Spring
body: <p>There are a few similar answered questions from around 2013/2014 but the solutions do not seem to work for me, so I am hoping that something has perhaps changed since then and that I am not missing something glaringly obvious. (new project: <em><strong>spring-boot 2.0.2.RELEASE</strong></em> and <em><strong>hibernate 5.2.17.Final</strong></em>)</p>
  <p><strong>The issue:</strong> I have an entity that contains a OneToOne (FetchType.LAZY) mapping to another entity, both of which are tables in a MySQL database. I would like the mapping between the two entities to be lazy such that hibernate does not perform a second query to retrieve the mapped entity. The association will never be null, i.e. not optional.</p>
  <p><strong>Expected:</strong> Given the two entities, e.g. <em>Person</em> and <em>Address</em> (as described below), when making the HQL or JPA request to retrieve one <em>Person</em> from the database I would expect (and want) to see only the following hibernate sql query:</p>
  <blockquote>
  <p>Hibernate: select person0_.id as id1_1_ from person person0_</p>
  </blockquote>
  <p><strong>Actual:</strong> Instead, I also see an eager fetch to get the <em>Address</em> entity:</p>
  <blockquote>
  <p>Hibernate: select person0_.id as id1_1_ from person person0_</p>
  <p>Hibernate: select address0_.id as id1_0_0_ from address address0_ where address0_.id=?</p>
  </blockquote>
  <p><strong>Attempted solutions:</strong> I have tried variations of the following:</p>
  <ul>
  <li>setting <code>optional = false</code> (<a href="https://stackoverflow.com/questions/17987638/hibernate-one-to-one-lazy-loading-optional-false">Hibernate: one-to-one lazy loading, optional = false</a>)</li>
  <li>adding the <code>LazyToOneOption.NO_PROXY</code> annotation (<a href="https://stackoverflow.com/questions/45107084/hibernate-lazy-loading-with-lazytoonelazytooneoption-no-proxy">Hibernate Lazy Loading with @LazyToOne(LazyToOneOption.NO_PROXY)</a>)</li>
  <li>ignoring mapping during serialisation/deserialisation with <code>@JsonIgnore</code></li>
  </ul>
  <p>Any help would be greatly appreciated!</p>
  <hr />
  <p><strong>Simplified example to reproduce issue:</strong> For a simplified example I used as reference this post in which the OP states that they have a working solution: <a href="https://stackoverflow.com/questions/17987638/hibernate-one-to-one-lazy-loading-optional-false">Hibernate: one-to-one lazy loading, optional = false</a></p>
  <p>I created a new Spring Boot project following this tutorial: <a href="https://www.callicoder.com/spring-boot-rest-api-tutorial-with-mysql-jpa-hibernate/" rel="nofollow noreferrer">https://www.callicoder.com/spring-boot-rest-api-tutorial-with-mysql-jpa-hibernate/</a> with the initial project generated through <a href="http://start.spring.io/" rel="nofollow noreferrer">http://start.spring.io/</a> (<em>Maven</em> + <em>Java</em> + <em>Spring Boot 2.0.2</em> and dependencies <em>Web</em> + <em>JPA</em> + <em>MySQL</em> + <em>DevTools</em>)</p>
  <p>The entity (<em>Person</em>) I want to query is defined as follows:</p>
  <pre><code>@Entity
  public class Person {
      @Id
      @SequenceGenerator(name = &quot;person_sequence&quot;, sequenceName = &quot;sq_person&quot;)
      @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = &quot;person_sequence&quot;)
      @Column(name = &quot;id&quot;)
      private long personID;
  
      @LazyToOne(value = LazyToOneOption.NO_PROXY)
      @OneToOne(mappedBy = &quot;person&quot;, cascade = CascadeType.ALL, optional = false, fetch = FetchType.LAZY)
      @JsonIgnore
      private Address address;
      // .. getters, setters
  }
  </code></pre>
  <p>The mapped entity (<em>Address</em>) is defined as:</p>
  <pre><code>@Entity
  public class Address {
      @Id
      @Column(name = &quot;id&quot;, unique = true, nullable = false)
      @GeneratedValue(generator = &quot;gen&quot;)
      @GenericGenerator(name = &quot;gen&quot;, strategy = &quot;foreign&quot;, parameters = @Parameter(name = &quot;property&quot;, value = &quot;person&quot;))
      private long personID;
  
      @PrimaryKeyJoinColumn
      @OneToOne(fetch = FetchType.LAZY)
      private Person person;
  }
  </code></pre>
  <p>Application entry:</p>
  <pre><code>@SpringBootApplication
  public class OneToOneMappingApplication {
  
      public static void main(String[] args) {
          SpringApplication.run(OneToOneMappingApplication.class, args);
      }
  }
  </code></pre>
  <p>JpaRepository:</p>
  <pre><code>@Repository
  public interface PersonRepository extends JpaRepository&lt;Person, Long&gt; {
  }
  </code></pre>
  <p>RestController:</p>
  <pre><code>@RestController
  @RequestMapping(&quot;/api&quot;)
  public class PersonController {
  
      @Autowired
      PersonRepository personRepository;
  
      // Get All Persons
      public List&lt;Person&gt; getAllPersons() {
          return personRepository.findAll();
      }
  }
  </code></pre>
  <p>In the application.properties I have requested spring jpa to show the SQL:</p>
  <pre><code>## Spring DATASOURCE (DataSourceAutoConfiguration &amp; DataSourceProperties)
  spring.datasource.url = jdbc:mysql://localhost:3306/onetone_app?useSSL=false
  spring.datasource.username = username
  spring.datasource.password = password
  # Show SQL
  spring.jpa.show-sql = true
  
  ## Hibernate Properties
  # The SQL dialect makes Hibernate generate better SQL for the chosen database
  spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
  
  # Hibernate ddl auto (create, create-drop, validate, update)
  spring.jpa.hibernate.ddl-auto = update
  
  # Bytecode enhancement for NO_PROXY usage (?)
  hibernate.ejb.use_class_enhancer = true
  </code></pre>
  <p>One <em>Person</em> with id = 0 and one <em>Address</em> with id = 0 were inserted in the database in order to make the above test.</p>