adr*_*mir 6 hibernate lazy-loading
我在Student和之间有一个 one2one 关系Address。我希望firstName和lastName字段Student被延迟加载。我也想懒惰的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也lastName和address字段:
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 并且结果相同)
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=?
  ----------++++++++++++++-----------
有两个基本资源可以正确理解这个问题。首先,属性的延迟加载不是标准设置。看:
Hibernate 支持延迟获取单个属性。这种优化技术也称为获取组。请注意,这主要是一项营销功能;优化行读取比优化列读取重要得多。但是,在极端情况下,仅加载类的某些属性可能很有用。
其次,基于上述 doc 部分,有一篇关于此的详细文章:
虽然这和NHibernate有关,但内容是一样的,因为这个特性来自Hibernate。
我们可以在那里阅读:
多个惰性属性呢?NHibernate 支持它们,但您需要记住一件事。NHibernate 将加载实体的所有惰性属性,而不仅仅是立即访问的属性。出于同样的原因,您不能急切地从 HQL 中加载实体的某些惰性属性。
再一次,我们可以理解lazy属性的设置不是标准设置。它适用于一些非常具体的情况,例如:
此功能主要用于特殊情况,例如Person.Image、Post.Text等。像往常一样,过度使用它时要小心。
总结:延迟加载属性(值类型/字符串,而不是关联)适用于特殊情况。它应该可以帮助我们避免加载一些巨大的列。但是,一旦访问了这样的属性,所有其他属性也会加载
| 归档时间: | 
 | 
| 查看次数: | 10654 次 | 
| 最近记录: |