2013-04-21 57 views
2

我有类A,B和C. A有一个属性B(manytoone)和B有一个属性C(onetomany)。这些类看起来像下面的人(shortend到相关属性):收集不加载,如果豆之前关系加载

class A { 
    [...] 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "fkb", nullable = false) 
    private B b; 
    [...] 
} 

class B { 
    [...] 
    @OneToMany(mappedBy = "b") 
    @Cascade(value = { CascadeType.ALL }) 
    private Set<C> cs; 

    public Set<C> getCs() { 
    return cs; 
    } 
    [...] 
} 

class C { 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "fkb", nullable = false) 
    private B b; 
} 

现在的问题是,根据我在其中负荷和烧烤铯在B收集不工作的顺序:

// outputs correct count of Cs per B 
List<B> bs = session.createCriteria(B.class).list(); 
for (B b : bs) { 
    System.out.println(b.getCs().size()); 
} 

// outputs always 0 
List<A> as = session.createCriteria(A.class).list(); 
List<B> bs = session.createCriteria(B.class).list(); 
for (B b : bs) { 
    System.out.println(b.getCs().size()); 
} 

以下调试我已经这样做:

  • 在第二码休眠触发select语句来加载铯
  • 在第一个代码中,返回的B是B类型,而Cs的集合有类型org.hibernate.collection.PersistentSet
  • 在第二个代码中,返回的B是B _ $$ _ javassist_58类型,并且Cs的类型具有类型java.util.HashSet

我正在使用Hibernate 3.8.3。

+0

如果你根本没有加载A,问题依然存在吗?在第二个代码中,B的类型为“javassist”是可以的,因为它是一个代理,但奇怪的是,如果它是由Hibernate加载的,你的Set 是一个HashSet。 – 2013-05-20 22:41:12

+0

如果我不加载因为问题没有发生(这是第一个代码示例)。只有当As在B之前加载时才会出现问题。 – Werzi2001 2013-05-21 06:05:18

+0

如果您不问大小,而是对b.getCs()执行foreach并从c实例中打印一些变量,会发生什么? (是的,这很奇怪,但你知道,与休眠...:D) – 2013-05-21 07:47:23

回答

0

你可以尝试以下操作:

1)由A进入您的乙实例:

List<A> as = session.createCriteria(A.class).list(); 
for (A a : as) { 
    for(C c : a.getB().getCs()){ 
     System.out.println(c); 
    } 
} 

2)使用这个标准装B:

List<B> bs = session.createCriteria(B.class).setFetchMode("cs", FetchMode.EAGER).list(); 
for (B b : bs) { 
    System.out.println(b.getCs().size()); 
} 

编辑:做你认为你的项目有可能以不同的方式查询你的数据库?例如,你可以试试这个(使用HQL):

List<B> bs = getSession().createQuery("Select b From B b").list(); 
+0

感谢您的答案,但1和2都不适用于我。这两次显示的大小仍然是0.我甚至试图从构造函数中删除初始化,但是这导致了NPE,所以hibernate并没有设置集合。我不能使用HQL,因为整个应用程序是为条件查询设计的。尽管我使用你的HQL尝试过,但大小仍然为0. – Werzi2001 2013-05-21 12:41:27

+0

如果删除A中的B的懒惰取指怎么办? – 2013-05-21 12:54:59

+0

如果我设置F etchMode.EAGER然后它的工作。但我认为我不能使用它,因为每当我加载A时加载所有的B会花费太多的开销。 – Werzi2001 2013-05-21 14:11:55