当前位置:编程学习 > JAVA >>

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类:

public abstract class AbstractExpertProfession  implements java.io.Serializable {
    // Fields    
     private ExpertProfessionId id;
     private Short majorProfession;
     ......
}
--------------------编程问答-------------------- 你确定arg.get("id");对应的id有记录? --------------------编程问答-------------------- 之前说我连续回复,因此最重要的一段代码还没贴上来。
贴一下出问题地方的程序片段。

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 开发
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,