hibernate - 当要求加载惰性字段时,Hibernate 会加载所有惰性字段

标签 hibernate lazy-loading

我在学生地址之间有一个一对一的关系。我希望 StudentfirstNamelastName 字段被延迟加载。我还想为 address 字段添加惰性。

这些是我的实体类:

@Entity
@Table(name = "students")
public class Student {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @OneToOne(mappedBy = "student", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
  @LazyToOne(LazyToOneOption.NO_PROXY)
  private Address address;

  @Basic(fetch = FetchType.LAZY)
  @Column(name = "first_name")
  private String firstName;

  @Basic(fetch = FetchType.LAZY)
  @Column(name = "last_name")
  private String lastName;

  // getters and setters
}

地址类:

@Entity
@Table(name = "addresses")
public class Address {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @OneToOne
  @JoinColumn(name = "s_id")
  private Student student;

  @Column
  private String street;

  // getters and setters
}

我的测试方法如下所示(Java 8 lambda 只是在后面创建一个实体管理器并在事务中执行所有操作):

@Test
public void dummyTest() {
  JPA_UTILS.runInTransaction(e -> {
    Student s = e.find(Student.class, 150L);
    System.out.println("----------++++++++++++++-----------");
    s.getFirstName();
    System.out.println("----------++++++++++++++-----------");
  });
}

因此,我在这里从数据库加载现有学生,然后获取惰性属性 firstName (映射到 first_name 列)。问题是 Hibernate 不仅加载 firstName,还加载 lastNameaddress 字段:

just.hibernate.one2one.TestApp > dummyTest STANDARD_OUT
  Hibernate: 
    select
      student0_.id as id1_1_0_ 
    from students student0_ 
    where student0_.id=?
  ----------++++++++++++++-----------
  Hibernate: 
     /* sequential select just.hibernate.one2one.Student */
    select
      student_.first_name as first_na2_1_,
      student_.last_name as last_nam3_1_ 
    from students student_ 
    where student_.id=?
  Hibernate: 
    /* load just.hibernate.one2one.Address */
    select
      address0_.id as id1_0_1_,
      address0_.street as street2_0_1_,
      address0_.s_id as s_id3_0_1_,
      student1_.id as id1_1_0_ 
    from addresses address0_ 
    left outer join students student1_  on address0_.s_id=student1_.id 
    where address0_.s_id=?
  ----------++++++++++++++-----------

我不想要这种行为,我只想加载我请求的内容。有人可以帮我找出问题所在吗?

谢谢

更新1:

检测是用maven完成的,我只发布相关代码(我已经尝试过使用gradle并得到相同的结果)

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-antrun-plugin</artifactId>
  <executions>
    <execution>
      <phase>process-classes</phase>
      <goals>
        <goal>run</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <tasks>
      <taskdef name="instrument" classname="org.hibernate.tool.instrument.javassist.InstrumentTask">
        <classpath>
          <path refid="maven.runtime.classpath" />
          <path refid="maven.plugin.classpath" />
        </classpath>
      </taskdef>
      <instrument verbose="false">
        <fileset dir="${project.build.outputDirectory}">
          <include name="**/*.class"></include>
        </fileset>
      </instrument>
    </tasks>
  </configuration>
</plugin>

最佳答案

有两个重要的资源可以正确理解这个问题。首先,属性的延迟加载不是标准设置。请参阅:

Hibernate supports the lazy fetching of individual properties. This optimization technique is also known as fetch groups. Please note that this is mostly a marketing feature; optimizing row reads is much more important than optimization of column reads. However, only loading some properties of a class could be useful in extreme cases.

其次,基于上述文档部分,有一篇详细的文章:

虽然这与 NHibernate 有关,但内容是相同的,因为该功能来自 Hibernate。

我们可以在那里阅读:

What about multiple lazy properties? NHibernate support them, but you need to keep one thing in mind. NHibernate will load all the entity’s lazy properties, not just the one that was immediately accessed. By that same token, you can’t eagerly load just some of an entity’s lazy properties from HQL.

同样,我们可以理解属性的lazy设置不是标准设置。它适用于一些非常具体的情况,例如:

This feature is mostly meant for unique circumstances, such as Person.Image, Post.Text, etc. As usual, be cautious in over using it.

摘要:延迟加载属性(ValueTypes/字符串,而不是关联)适用于特殊情况。它应该帮助我们避免加载一些巨大的列。但是,一旦访问这样的属性,所有其他属性也会加载

关于hibernate - 当要求加载惰性字段时,Hibernate 会加载所有惰性字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25487148/

相关文章:

hibernate - Fetch Type LAZY 仍然导致 Eager 加载 Hibernate Spring 数据

javascript - 在 highcharts 中选择绘图时获取图表的坐标

java - Hibernate - 避免 LazyInitializationException - 从代理和 session 中分离对象

java - 带有遗留映射表的 Hibernate Annotation

Spring + Hibernate 保存()不工作

java - 使用 JPA 无法获取自动生成的 ID

oop - 延迟加载 vs thunking?

java - 在 Hibernate 中映射具有多个 ID 的扩展实体

Spring MVC-通过token-confirm账户方式激活账户返回404错误

Angular 懒加载动态组件