以编程方式指定休眠中多对一的延迟加载

发布于 2024-11-30 02:08:50 字数 886 浏览 3 评论 0原文

我正在使用 Hibernate 3.6 和 Spring 3.0.5。

我有以下用户对象的映射

<class name="foo.User" table="FOO_USER">
    <id  column="USER_ID" name="id" type="java.lang.Integer">
        <generator class="identity"/>
    </id>


    <property name="firstName" column="FIRST_NAME" type="java.lang.String" length="100"/>
    ...
    <many-to-one name="organization" column="ORGANIZATION_ID class="foo.Organization" not-null="true" update="false" />
    ...

用户与组织具有多对一关系。通常,我希望立即加载该关系,因此映射坚持默认设置lazy=false(不指定任何内容)。

在某些情况下,我不想急切地加载组织。我尝试用 Criteria 指定这一点

(User)getSession().createCriteria(User.class)
            .add(Restrictions.eq("id",id))
            .setFetchMode("organization", FetchMode.SELECT)
            .uniqueResult();

,但提取模式被忽略。 Hibernate 仍然急切地加载组织关系。我已经为此绞尽脑汁几个小时了。任何帮助将不胜感激。

I am using Hibernate 3.6 with Spring 3.0.5.

I have the following mapping for a User object

<class name="foo.User" table="FOO_USER">
    <id  column="USER_ID" name="id" type="java.lang.Integer">
        <generator class="identity"/>
    </id>


    <property name="firstName" column="FIRST_NAME" type="java.lang.String" length="100"/>
    ...
    <many-to-one name="organization" column="ORGANIZATION_ID class="foo.Organization" not-null="true" update="false" />
    ...

The User has a many-to-one relationship with Organization. Usually, I want that relationship to be eagerly loaded, so the mapping sticks with the default setting of lazy=false (by not specifying anything).

There is a certain case where I do not want to eagerly load the Organization. I tried specifying this with a Criteria

(User)getSession().createCriteria(User.class)
            .add(Restrictions.eq("id",id))
            .setFetchMode("organization", FetchMode.SELECT)
            .uniqueResult();

But the fetch mode is being ignored. Hibernate still eagerly loads the Organization relationship. I've been knocking my head against this for a few hours. Any help would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眼泪也成诗 2024-12-07 02:08:50

最好将关联映射为惰性关联并使用获取策略来调整性能。我不相信有一种方法可以将某些东西映射为惰性,然后在特定实例中使其变得非惰性。当然 fetch=select 不会这样做,因为这并不意味着懒惰。请参阅“提高性能”的第 21.1 节 在参考手册中了解概念的解释。

It's always best to leave associations mapped as lazy and use fetching strategies to tune performance. I don't believe there's a way to map something as lazy and then make it un-lazy in a particular instance. Certainly fetch=select won't do it, as that doesn't imply anything about laziness. See section 21.1 of "Improving Performance" in the reference manual for an explanation of the concepts.

风轻花落早 2024-12-07 02:08:50

FetchType 可以使用 fetchProfiles 以编程方式设置,

例如:假设有一个 Employee 类,它有两个子类 Address 和 Department Fetch 配置文件,这些可以在 Employee 类中设置。

@FetchProfiles({ @FetchProfile(name = "emp_address", fetchOverrides = { @FetchProfile.FetchOverride(entity = Employee.class, association = "addresses", mode = FetchMode.JOIN) }), @FetchProfile(name = "emp_department", fetchOverrides = { @FetchProfile.FetchOverride(entity = Employee.class, association = "departments", mode = FetchMode.JOIN) })}) public class Employee {

@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set addresses;

@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set departments; }

当您检索员工记录时,您可以启用 fetchprofile。如果启用了获取配置文件,则将急切地获取子对象,因为您正在执行联接

session.enableFetchProfile("emp_address");
session.enableFetchProfile("emp_department");
Criteria criteria = session.createCriteria(Employee.class); 
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 
List employees = criteria.list();

FetchType can be set programatically using fetchProfiles

e.g.: Consider there is an Employee class and it has two child classes Address and Department Fetch profiles for these can be set in the Employee class.

@FetchProfiles({ @FetchProfile(name = "emp_address", fetchOverrides = { @FetchProfile.FetchOverride(entity = Employee.class, association = "addresses", mode = FetchMode.JOIN) }), @FetchProfile(name = "emp_department", fetchOverrides = { @FetchProfile.FetchOverride(entity = Employee.class, association = "departments", mode = FetchMode.JOIN) })}) public class Employee {

@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set addresses;

@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set departments; }

You can enable the fetchprofile When you are retrieve Employee record. If the fetch profile is enable then the child objects are eagerly fetch because you are doing a join

session.enableFetchProfile("emp_address");
session.enableFetchProfile("emp_department");
Criteria criteria = session.createCriteria(Employee.class); 
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 
List employees = criteria.list();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文