0

我想知道:FetchType.LAZY在一个(多)对多中使用 DAO 模式有什么意义?基本没用?一旦您在 DAO 之外(例如,实际工作是否完成),您就无法获取相关数据,因为您不再处于休眠会话中。

让我们举个例子:

StudentClass。一个学生上很多课。他现在登录系统并从系统中检索他的学生实体对象。

application layer -> Service Layer -> DAO

现在学生想看看他参加了哪些课程,并且LazyInitializationException因为我们在 DAO 之外而发生了 oops a。

有哪些方法可以防止这种情况?我喜欢用谷歌搜索时间,但没有找到解决方案,除了在离开 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 一样,我会在几小时前达到预期的行为......

4

2 回答 2

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,则相同)。

于 2012-10-08T11:12:14.417 回答
0

解决问题的一种方法是使用OpenSessionInViewFilter过滤器。

<filter>
    <filter-name>hibernateSessionFilter</filter-name>
    <filter-class>
        org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
    </filter-class>
</filter>
于 2012-10-08T11:12:30.360 回答