使用hibernate禁用属性/集合加载

时间:2009-06-02 13:52:31

标签: java hibernate

有没有人知道如何防止hibernate加载集合或多对一关联?

我有一个用例,我需要加载一个对象,但调用程序可以确定是否加载了某些属性。对于集合的一部分也是如此:必须获取某些行,而不是其他行。

域类:

public class SomeClass {
    private SomeClass parent;
    private Set<OtherClass> collection;
}

public class OtherClass {
    private Date startDate;
    private Date endDate;
}

public class Dao {
    public SomeClass loadClass(long id, boolean parents, boolean historicalData) {
         // load SomeClass
         // if parents == true, load parent, otherwise leave <null>
         // if historicalData == false, load OtherClass where endDate == <null>
    }
}

我已经想到了2个解决方案,但是如果可能的话,我可以使用标准或查询。

解决方案1是不要将SomeClass与OtherClass以及hibernate配置中的父/子关系进行关联,并在代码中加载关联。
解决方案2是定义具有不同实体名称的不同映射,并提供特殊情况。

在这种情况下,调用者可以在其他JVM或事务中,因此会话被关闭,因此延迟加载不是一个真正的选择。

4 个答案:

答案 0 :(得分:2)

你应该利用Hibernate的延迟加载功能。 您可以注释像:

这样的集合
@OneToMany(fetch=FetchType.LAZY)

在这种情况下,如果您实际在代码中访问它,Hibernate只会加载该集合。

答案 1 :(得分:1)

编写Criteria查询并使用setFetchMode方法更改父级的获取行为,并使用createCriteria方法另外查询集合。

Criteria c = session.createCriteria(SomeClass.class).add(Restrictions.idEq(id));

if (parents) {
  c.setFetchMode("parents", FetchMode.EAGER);
}
if (historicalData) {
  c.createCriteria("collection", Criteria.LEFT_JOIN)
   .add(Restriction.lt("date", date))
   .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
}
return c.uniqueResult();

...这是假设默认设置为LAZY(根据Hibernate默认设置)。

Hibernate中没有选项可以保留具有值的属性 null (在这种情况下是多对一关联。该字段将包含一个可用于延迟加载的代理引用的对象。如果代码从不接触对象,它将不会被加载。

对于集合也是如此:如果没有获取,它将包含一个集合代理(一个实现集合接口的hibernate类),它只会在调用时加载内容。

答案 2 :(得分:0)

像上面的海报一样使用@OneToMany(fetch=FetchType.LAZY),但请注意,延迟提取集合和关联是Hibernate 3.x中的默认提取类型。

答案 3 :(得分:0)

我认为#2是最好的解决方案。虽然我自己没有使用过这个解决方案,但我知道有其他成功的开发人员。