hibernate多对多查询问题
背景描述:现有表a和b,两表之间存在多对多关系,该关系以表c形式存在,其主键由a主键aid及b主键bid组合生成。经hibernate映射后分别生成类A、类B及类AB。
A中对B的引用表示为:private Set<B> b = new HashSet<B>(0);
B中对A的引用表示为:private Set<A> a = new HashSet<A>(0);
工程中需要通过客户端传来的对象A查询出它所对应的所有对象B,客户端用Flex进行开发。由于Flex传来的对象为ASObject类型,因此需要先从该对象中提取出属性id,再根据id找到对象A,最后得到A对应的所有B。程序段如下:
public List<B> search(ASObject arg){
ADAO ad = new ADAO();
Integer id = (Integer)arg.get("id");
A a = ad.findById(id);
Set<B> b = a.getB();
......
}
问题描述:
对象A无法得到它所对应的对象B集合。经查,发现b为null,但是根据类定义,对象A中的B集合应以被初始化,即使某个对象A没有任何与之易做图的对象B,也可得到b.isEmpty()为true的结果,而不应该是b为null。之后再次试验,先利用固定值得到对象A,如A a = ad.findById(10),再获取其对应的B集合则不会出现此问题。但不管哪种情况,对象A都能够正确获取,且A的其它属性也是正确的。
不知何故,向各位请教,谢谢!
--------------------编程问答-------------------- 不知何故,向各位请教,谢谢! --------------------编程问答-------------------- 代码应该不止这些吧。。。我还是觉得你应该把相应的 配置信息都贴出来,,,,等大神帮你 --------------------编程问答-------------------- 背景描述中有些偏差,补充一下:
A中对AB的引用表示为:private Set<AB> ab = new HashSet<AB>(0);
B中对AB的引用表示为:private Set<AB> ab = new HashSet<AB>(0);
程序片段做相应改动:
public List<B> search(ASObject arg){
ADAO ad = new ADAO();
Integer id = (Integer)arg.get("id");
A a = ad.findById(id);
Set<AB> ab = a.getAB();
......
}
其它描述大致不变,即对象ab总为null --------------------编程问答-------------------- 贴一下实际工程中的配置文件。
a表->A类的映射文件:
<hibernate-mapping>
<class name="pojo.ExpertInfo" table="ep_info" catalog="expertdb">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="name" length="45" />
</property>
......
<set name="expertProfessions" inverse="true" lazy="extra">
<key>
<column name="ep_info_id" not-null="true" />
</key>
<one-to-many class="pojo.ExpertProfession" />
</set>
<set name="accounts" inverse="true" lazy="extra">
<key>
<column name="ep_info_id" not-null="true" />
</key>
<one-to-many class="pojo.Account" />
</set>
</class>
</hibernate-mapping>
b表->B类的映射文件:
<hibernate-mapping>
<class name="pojo.ProfessionCategory" table="pf_category" catalog="expertdb">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native"></generator>
</id>
<property name="firstnum" type="java.lang.String">
<column name="firstnum" length="45" />
</property>
......
<set name="expertProfessions" inverse="true" lazy="extra">
<key>
<column name="pf_category_id" not-null="true" />
</key>
<one-to-many class="pojo.ExpertProfession" />
</set>
</class>
</hibernate-mapping>
ab表->AB类的映射文件:
--------------------编程问答-------------------- 贴一下类声明。
<hibernate-mapping>
<class name="pojo.ExpertProfession" table="ep_info_has_pf_category" catalog="expertdb">
<composite-id name="id" class="pojo.ExpertProfessionId">
<key-many-to-one name="expertInfo" class="pojo.ExpertInfo">
<column name="ep_info_id" />
</key-many-to-one>
<key-many-to-one name="professionCategory" class="pojo.ProfessionCategory">
<column name="pf_category_id" />
</key-many-to-one>
</composite-id>
<property name="majorProfession" type="java.lang.Short">
<column name="major_profession"/>
</property>
</class>
</hibernate-mapping>
A类:
public abstract class AbstractExpertInfo implements java.io.Serializable {
// Fields
private Integer id;
private String name;
......
private Set<ExpertProfession> expertProfessions = new HashSet<ExpertProfession>(0);
private Set<Account> accounts = new HashSet<Account>(0);
......
}
B类:
public abstract class AbstractProfessionCategory implements java.io.Serializable {
// Fields
private Integer id;
private String firstnum;
......
private Set<ExpertProfession> expertProfessions = new HashSet<ExpertProfession>(0);
......
}
AB的组合id类:
public abstract class AbstractExpertProfessionId implements java.io.Serializable {
// Fields
private ExpertInfo expertInfo;
private ProfessionCategory professionCategory;
......
}
AB类:
--------------------编程问答-------------------- 你确定arg.get("id");对应的id有记录? --------------------编程问答-------------------- 之前说我连续回复,因此最重要的一段代码还没贴上来。
public abstract class AbstractExpertProfession implements java.io.Serializable {
// Fields
private ExpertProfessionId id;
private Short majorProfession;
......
}
贴一下出问题地方的程序片段。
public List<ExpertInfo> searchByProfession(List<ASObject> professions){
ProfessionCategoryDAO pcd = new ProfessionCategoryDAO();
List<ExpertInfo> experts = new ArrayList<ExpertInfo>();
experts.add(new ExpertInfo());
for(ASObject professionAS:professions){
Integer id = (Integer)professionAS.get("id");
ProfessionCategory pc = pcd.findById(id);
Set<ExpertProfession> prfSet = pc.getExpertProfessions();
if(prfSet!=null){
Iterator<ExpertProfession> it = prfSet.iterator();
while(it.hasNext()){
ExpertInfo expert = it.next().getId().getExpertInfo();
if(expert!=null && experts.contains(expert)==false){
experts.add(expert);
}
}
}
}
experts.remove(0);
return experts;
}
其中prfSet总为null,而根据类定义,它应该是已经被初始化过的。
回复楼上:
每个id都能取到其对应的对象,数据库里也有相应的行,这个没有问题。 --------------------编程问答-------------------- 目前已通过其它方法绕过该问题从而保证了功能的实现,但该问题仍然不知道是怎么产生的。是我描述得不清楚还是其它什么原因,为何回复寥寥? --------------------编程问答-------------------- 配置问题你要的是级联查询效果,设置一下cascade值 --------------------编程问答-------------------- 学习了一下,没有设置cascade值,而是将inverse由true改成了false,则set没有出现null的情况,但是又引发了其它问题(不过与本贴所提问题无直接关系)。
感谢你的回复!
补充:Java , Web 开发