2009-06-02 93 views
0

加载没有人知道如何防止加载集合或多对一的关联休眠?禁用属性/集合与休眠

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

域类:

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个解决方案,但我ONT到现在,如果可能与标准或查询。

解决方案1不会将SomeClass关联到OtherClass和Hibernate配置中的父/子关系,并在代码中加载关联。
解决方案2是定义不同的映射与不同的实体名称与服务的特殊情况。

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

回答

1

编写条件查询并使用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没有选择离开性质这确实有一个值(在这种情况下,许多-to-one关联,现场将举行,可用于懒洋洋地加载称为对象的代理。如果代码从未触及对象,则它将不会被加载。

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

2

您应该利用Hibernate的延迟加载功能。 您可以标注喜欢收藏:

@OneToMany(fetch=FetchType.LAZY) 

在这种情况下,休眠只加载集合,如果你确实在代码中访问它。

+0

我无法控制是否访问某个属性,因为该对象返回给客户端,可能运行在不同的JVM或trans行动。我将在问题中澄清这一点。 – Salandur 2009-06-02 14:12:38

+0

在这种情况下,我建议您使用基于您的用例填充的数据传输对象。 – 2009-06-02 14:56:04

0

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

0

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