FetchType的区别是什么。LAZY和FetchType。Java持久性API中的EAGER ?
当前回答
据我所知,这两种类型的取回取决于你的要求。
FetchType。LAZY是按需的(即当我们需要数据时)。
FetchType。EAGER是即时的(即在我们的需求到来之前,我们不必要地获取记录)
其他回答
对集合的EAGER加载意味着在获取它们的父类时,它们被完全获取。如果你有课程并且它有List<Student>,所有的学生在课程被获取的同时从数据库中获取。
另一方面,LAZY意味着只有当您试图访问List的内容时才会获取它们。例如,调用course.getStudents().iterator()。调用List上的任何访问方法都将启动对数据库的调用以检索元素。这是通过围绕列表(或集合)创建代理来实现的。所以对于惰性集合,具体的类型不是ArrayList和HashSet,而是PersistentSet和PersistentList(或PersistentBag)。
有一个小小的评论: 如果你使用惰性类型,如果你关闭会话,你以后将不能从数据库中获取数据(参见下面的输出)。
但是对于Eager类型,你在获取Instructor的同时获取数据,所以在session.close()之后,你将能够使用/显示这些课程列表数据。
@OneToMany(//fetch = FetchType.EAGER,
fetch = FetchType.LAZY,
mappedBy = "instructor",
cascade = {CascadeType.DETACH, CascadeType.MERGE,
CascadeType.PERSIST, CascadeType.REFRESH})
private List<Course> courseList;
我建议在调试模式下尝试这两种方法。在这种情况下,我使用惰性类型,你可以看到。
try {
//start the transaction
session.beginTransaction();
//Get instructor from database
int instructorId = 7;
Instructor tempInstructor = session.get(Instructor.class,instructorId);
System.out.println("Instructor: "+tempInstructor);
//commit transaction
session.getTransaction().commit();
//close session
session.close();
//since courselist is lazy loaded... this should fail
//so in here we are not able to fetch courselist data
//get courses
System.out.println("Courses "+tempInstructor.getCourseList() );
System.out.println("Done!");
} finally {
session.close();
factory.close();
}
}
输出异常:
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.exercise.hibernate.entity.Instructor.courseList, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:606)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:218)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:585)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:149)
at org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:621)
at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453)
at java.base/java.lang.StringConcatHelper.simpleConcat(StringConcatHelper.java:408)
at com.exercise.hibernate.main.EagerLazyLoading.main(EagerLazyLoading.java:56)
据我所知,这两种类型的取回取决于你的要求。
FetchType。LAZY是按需的(即当我们需要数据时)。
FetchType。EAGER是即时的(即在我们的需求到来之前,我们不必要地获取记录)
有时你有两个实体它们之间有关系。例如,你可能有一个实体叫University,另一个实体叫Student,一个University可能有很多Student:
University实体可能有一些基本属性,如id、名称、地址等,以及一个名为students的集合属性,它返回给定大学的学生列表:
public class University {
private String id;
private String name;
private String address;
private List<Student> students;
// setters and getters
}
现在,当您从数据库加载University时,JPA将为您加载它的id、名称和地址字段。但是你有两种选择:
将它与其他字段一起加载(即急切地加载),或者 在调用大学的getStudents()方法时按需加载它(即惰性加载)。
当一所大学有很多学生时,加载所有的学生并不是有效的,特别是当他们不需要的时候,在这种情况下,你可以声明你想要在实际需要学生的时候加载他们。这被称为惰性加载。
下面是一个例子,学生被明确地标记为急切加载:
@Entity
public class University {
@Id
private String id;
private String name;
private String address;
@OneToMany(fetch = FetchType.EAGER)
private List<Student> students;
// etc.
}
这里有一个例子,学生被明确地标记为惰性加载:
@Entity
public class University {
@Id
private String id;
private String name;
private String address;
@OneToMany(fetch = FetchType.LAZY)
private List<Student> students;
// etc.
}
基本上,
LAZY = fetch when needed
EAGER = fetch immediately
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 原则-如何打印出真正的sql,而不仅仅是准备好的语句?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder