我想知道:使用DAO模式的一对(多对多)FetchType.LAZY
有什么意义?
它基本没用?一旦你在你的DAO之外(例如,实际工作已经完成),你就不能获取相关数据,因为你不再在休眠会话中了。
让我们举个例子:
Student
和Class
。一个学生上了很多课。他现在登录系统,并从系统中检索他的Student实体对象。
application layer -> Service Layer -> DAO
现在学生想要看看他参加了哪些课程,并且因为我们在DAO之外而发生了LazyInitializationException
。
有什么方法可以防止这种情况发生?我喜欢googled hours并没有找到解决方案,除了在离开DAO之前实际取出所有东西,这首先打败了懒惰的目的。 (已阅读OpenSessionViewFilter
,但这应该独立于应用程序层工作)
你如何以一种好的方式解决这个问题?什么是不受此影响的替代模式?
编辑:
我没有LazyInitializationException
以下设置:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.compound",
cascade = CascadeType.ALL, orphanRemoval = true)
@Fetch(FetchMode.JOIN)
有趣的是它一定是这样的。
删除@Fetch
- > LazyInitializationException
更奇怪的是,如果我删除orphanRemoval = true
,那么即使LazyInitializationException
也会出现@Fetch
。所以这两个都是必需的。
也许有人可以告诉我为什么会这样。目前我倾向于完全抛弃休眠,就像纯JDBC一样,我会在几个小时前达到预期的行为......
答案 0 :(得分:1)
您可以随时获取外键关系数据而无需相同的激情。由于您的会话不存在于应用程序层之外,因此您只需在检索数据并进行设置的方法中手动获取它。
应用层:
public List<SchoolClass> getSchoolClassesByStudent(Serializable identifier)
{
List<SchoolClasses> schoolClasses = // get classes by student using criteria or hql
return schoolClasses;
}
客户层:
public void loadSchoolClassesByStudent(Student student)
{
student.setSchoolClasses(application.getSchoolClassesByStudent(student.getId()));
}
我自己选择不支持我的休眠实体中的任何集合 我使用非常通用的方法获取所有子关系,我的服务器提供给我的客户端类似于此。
编辑:或者创建一些逻辑(拦截器?),如果数据在访问之前未经初始化并且使用通用方法初始化,则可以在DAO外部进行检查。 这也假设Hibernate jar是在客户端级别,这取决于这是一个好主意(如果未初始化的数据未设置为null,则相同)。
答案 1 :(得分:0)
解决问题的一种方法是使用OpenSessionInViewFilter
过滤器。
<filter>
<filter-name>hibernateSessionFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
</filter>