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
}
Run Code Online (Sandbox Code Playgroud)
地址类:
@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
}
Run Code Online (Sandbox Code Playgroud)
我的测试方法如下所示(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("----------++++++++++++++-----------");
});
}
Run Code Online (Sandbox Code Playgroud)
所以在这里我从数据库加载一个现有的学生,然后获取惰性属性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=?
----------++++++++++++++-----------
Run Code Online (Sandbox Code Playgroud)
我不想要这种行为,我只想加载我请求的内容。有人可以帮我找到问题吗?
谢谢
更新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=?
----------++++++++++++++-----------
Run Code Online (Sandbox Code Playgroud)
有两个基本资源可以正确理解这个问题。首先,属性的延迟加载不是标准设置。看:
Hibernate 支持延迟获取单个属性。这种优化技术也称为获取组。请注意,这主要是一项营销功能;优化行读取比优化列读取重要得多。但是,在极端情况下,仅加载类的某些属性可能很有用。
其次,基于上述 doc 部分,有一篇关于此的详细文章:
虽然这和NHibernate有关,但内容是一样的,因为这个特性来自Hibernate。
我们可以在那里阅读:
多个惰性属性呢?NHibernate 支持它们,但您需要记住一件事。NHibernate 将加载实体的所有惰性属性,而不仅仅是立即访问的属性。出于同样的原因,您不能急切地从 HQL 中加载实体的某些惰性属性。
再一次,我们可以理解lazy属性的设置不是标准设置。它适用于一些非常具体的情况,例如:
此功能主要用于特殊情况,例如Person.Image、Post.Text等。像往常一样,过度使用它时要小心。
总结:延迟加载属性(值类型/字符串,而不是关联)适用于特殊情况。它应该可以帮助我们避免加载一些巨大的列。但是,一旦访问了这样的属性,所有其他属性也会加载
| 归档时间: |
|
| 查看次数: |
10654 次 |
| 最近记录: |