hibernate加载对象图的正确方法是什么

时间:2011-08-25 16:58:46

标签: hibernate

假设我有3张桌子GrandCat,Cat和Kitt。他们有一对多的关系所以我有以下几个类。所有关联都是延迟加载。

GrandCat{
    int age;
    Set<Cat> cats;
} 

Cat{
   int age;
   Set<kitt> kitten;
   GrandCat grandCat;
}

Kit{
   String color;
   Cat cat;  
}

我想建立一个grandCat列表。条件是grandCat.age&gt; 10和Cat.age> 5并且具有至少一种颜色为黄色的kitt。当我做grandCat.getCats()时,只有猫满足条件返回。例如,我有以下猫。 像这样的关系

 grand 1(age>10)--> alex(age>5) ---> a(yellow),b,c             |
                |
                --> bob(age<5)  --->d,e(yellow)

 grand 2(age>10)  --> charlie(age<5) ---> f,g(yellow)
                   |
                   --> david(age>5)--->h
                   |
                   -->edward(age>5)-->j(yellow)
                   |
                   -->fay(age>5) --> i(yellow),k(yellow)

 other grandCats........

我希望返回GrandCats是grand 1和grand2就像这样

   grand1-->alex-->a
   grand2-->edward-->j
          |
          -->fay-->i,k

他们是一群巨型猫,猫和小猫,所以不要加载它们然后过滤。

我知道我可以使用

来实现它
select g,c,k from grandCat g inner join fetch g.cat c inner join fetch c.kitten k where g.age>10 and c.age>5 and k.color='yellow'. 

然后循环返回值以查看哪只猫属于哪个grandCat和cat对猫。但这有一些缺点,在grandcat和cat级别上有重复。因为他们回来了

  grand1-->alex-->a
  grand2-->edward-->j
  grand2-->fay-->i        
  grand2-->fay-->k

所以我需要比较它们并过滤,当有很多记录时,这需要时间并消耗资源。 任何人都有一个很好的方法加载这个?我应该使用3个hql吗?首先得到匹配的grandCat1和grand2

select g from grandCat g inner join fetch g.cat c inner join fetch c.kitten k where g.age>10 and c.age>5 and k.color='yellow'.

然后使用上次查询的grandcat返回查询cat,然后将cat放到grand.setcats()

select c from Cat c inner join fetch cat.grandCat g inner join fetch c.kitten k where g=:grandCat and c.age>5 and k.color='yellow'

然后查询小猫并做同样的事情?

select k from Kitt k inner join fetch k.cat c where c=:cat and k.color='yellow'
这似乎很乏味。

这样做的最佳方式是什么?顺便说一句,我希望返回的grandCat及其'猫和小猫仍然具有延迟加载能力,比如小猫有其他关联,我可以在以后通过延迟加载使用它们。

1 个答案:

答案 0 :(得分:0)

select distinct g from GrandCat g 
inner join fetch g.cat c 
inner join fetch c.kitten k 
where g.age>10 
and c.age>5 
and k.color='yellow'

应该做得很好。返回的爷爷只会在它的猫咪系列中拥有想要的猫,而每只猫只会在其小猫系列中拥有想要的小猫。

请注意,尽管Hibernate返回实体,但这些实体并未反映关联的实际情况。我会将它们视为只读对象,而不是试图以任何方式修改关联,因为它可能会产生灾难性的副作用。