我为User类和Pet类(以宠物商店为主题的学术Web项目)设置了“一对多”/“多对一”双向映射关系。每个用户都拥有宠物的集合。
似乎关系工作正常,因为当我执行查询以在NetBeans的HQL查询浏览器中选择我的数据库中的第一个用户时,我看到“Pets”属性列出了2个Java对象ID,可能是两个我通过外键引用的宠物( [HibernateBeans.Pet@76838e,HibernateBeans.Pet@b71950] )。
令人沮丧(并且错误地),当我传入与我成功查询的完全相同的用户时,下面的代码返回一个空集合:
public ArrayList<Pet> getPets(User user) {
Set<Pet> pets = null;
try {
session = HibernateUtil.getSessionFactory().getCurrentSession();
pets = user.getPets();
for (Pet p : pets) System.out.println(p.getPetName());
} catch (Exception e) {
System.out.println(e.getMessage());
}
return pets;
}
编辑:根据Tahir的建议,我已从Java类中删除了注释,现在严格使用POJO XML映射(但同样的问题仍然存在)。我的源代码已相应更新:
以下是相关的XML Hibernate映射:
User.hbm.xml:
<set name="pets" inverse="true">
<key>
<column name="UserID" not-null="true" />
</key>
<one-to-many class="HibernateBeans.Pet"/>
</set>
Pet.hbm.xml:
<many-to-one name="user" class="HibernateBeans.User" fetch="select">
<column name="UserID" not-null="true" />
</many-to-one>
对此问题的任何帮助都将不胜感激。虽然这是我第一次发帖提问,但StackOverflow已经在很多上挽救了我的生命。
提前致谢!
答案 0 :(得分:2)
另外,为了保存宠物对象的集合,你保存一个用户对象,你必须将一对多的cascade属性映射到“all”。它在下面指定。
<set name="pets" inverse="true" cascade="all" lazy="false">
<key column name="UserID" not-null="true" />
<one-to-many class="HibernateBeans.Pet"/>
</set>
尝试一下。它可能有用。
答案 1 :(得分:0)
您是否在同一个项目中同时使用基于XML和注释的映射?我建议使用单一方法(在您的情况下注释)。
您的XML映射版本未将User.pets声明为急切加载的属性。这可能是你看到一个空列表的原因。
修改强>
由于在切换到仅xml映射后仍然遇到问题,我建议您尝试以下操作:
new
keyword lazy="false"
尝试声明User.pets是急切加载的第2点和第3点仅用于帮助您进行调试。鉴于您没有急切地加载pets
,在关闭原始会话后尝试调用user.getPets()
的任何尝试都应该生成org.hibernate.LazyInitializationException
。
修改强>
要检查的另一件事是您没有手动为User.pets字段分配值。 Hibernate提供了一个自定义的集合实现,以便能够提供延迟初始化。