简体   繁体   中英

Why Hibernate executes SELECT query on lazy relationship attribute field

In my application, I have the following @Entity .

@Entity(name="DemoAccount")
@Table(name="staff")
@Getter @Setter @FieldNameConstants
@NoArgsConstructor
public class Account {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    protected Long id;
    @Column(name="username", nullable=false)
    private String userId;
    private String name;

    @ManyToOne(fetch=FetchType.LAZY)
    @LazyToOne(LazyToOneOption.NO_PROXY)
    @LazyGroup("nationality")
    @JoinColumn(name="nationality", referencedColumnName="code")
    private Nationality nationality;
}

I used Hibernate Bytecode Enhancer to define to-one relationship fields. When I execute my JPQL method to eagerly fetch the lazy fields, I'm seeing Hibernate execute all the joins properly.

2020-05-24 16:18:26,492 DEBUG [http-nio-9000-exec-1] org.hibernate.SQL   : 
    /* select
        generatedAlias0 
    from
        DemoAccount as generatedAlias0 
    where
        generatedAlias0.userId=:param0 */ select
            account0_.id as id1_61_0_,
            nationalit1_.id as id1_35_1_,
            account0_.name as name4_61_0_,
            account0_.username as username6_61_0_,
            nationalit1_.code as code2_35_1_,
            nationalit1_.name as name4_35_1_
        from
            staff account0_ 
        left outer join
            nationality nationalit1_ 
                on account0_.nationality=nationalit1_.code 
        where
            account0_.username=?
2020-05-24 16:18:26,492 TRACE [http-nio-9000-exec-1] org.hibernate.type.descriptor.sql.BasicBinder   : binding parameter [1] as [VARCHAR] - [90000010]

However, whenever I call account.getNationality().getName() , I always see the following select statement.

2020-05-24 16:18:26,506 DEBUG [http-nio-9000-exec-1] org.hibernate.SQL   : 
    /* sequential select
        com.ft.demo.db.customer.domain.Account */ select
            account_.nationality as nationa22_61_ 
        from
            staff account_ 
        where
            account_.id=?
2020-05-24 16:18:26,507 TRACE [http-nio-9000-exec-1] org.hibernate.type.descriptor.sql.BasicBinder   : binding parameter [1] as [BIGINT] - [660]

So if I have a list of 50 records, 50 additional select statements get executed. I'd be very grateful if you could tell me what I've done wrong.

FYI: I'm using the latest Spring Boot 2.2.7 and Hibernate is at 5.4.15.Final.

UPDATE :

Below is my Hibernate Bytecode Enhancer plugin configurations.

  <plugin>
    <groupId>org.hibernate.orm.tooling</groupId>
    <artifactId>hibernate-enhance-maven-plugin</artifactId>
    <version>${hibernate.version}</version>
    <executions>
      <execution>
        <configuration>
          <failOnError>true</failOnError>
          <enableLazyInitialization>true</enableLazyInitialization>
        </configuration>
        <goals>
          <goal>enhance</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

Make sure to have spring.jpa.open-in-view=false in your application.properties file. If you have it set to true you will end up querying database when you call get method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM