hibernate多对多查询问题

lavaholly 2013-12-17 11:14:25
背景描述:
现有表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的其它属性也是正确的。
不知何故,向各位请教,谢谢!

...全文
170 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
heboucheng 2013-12-19
  • 打赏
  • 举报
回复
配置问题你要的是级联查询效果,设置一下cascade值
lavaholly 2013-12-19
  • 打赏
  • 举报
回复
目前已通过其它方法绕过该问题从而保证了功能的实现,但该问题仍然不知道是怎么产生的。是我描述得不清楚还是其它什么原因,为何回复寥寥?
lavaholly 2013-12-19
  • 打赏
  • 举报
回复
学习了一下,没有设置cascade值,而是将inverse由true改成了false,则set没有出现null的情况,但是又引发了其它问题(不过与本贴所提问题无直接关系)。 感谢你的回复!
乔不思 2013-12-18
  • 打赏
  • 举报
回复
代码应该不止这些吧。。。我还是觉得你应该把相应的 配置信息都贴出来,,,,等大神帮你
lavaholly 2013-12-18
  • 打赏
  • 举报
回复
不知何故,向各位请教,谢谢!
lavaholly 2013-12-18
  • 打赏
  • 举报
回复
之前说我连续回复,因此最重要的一段代码还没贴上来。 贴一下出问题地方的程序片段。

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都能取到其对应的对象,数据库里也有相应的行,这个没有问题。
ncist_jianeng 2013-12-18
  • 打赏
  • 举报
回复
你确定arg.get("id");对应的id有记录?
lavaholly 2013-12-18
  • 打赏
  • 举报
回复
贴一下类声明。 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;
     ......
}
lavaholly 2013-12-18
  • 打赏
  • 举报
回复
贴一下实际工程中的配置文件。 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>
lavaholly 2013-12-18
  • 打赏
  • 举报
回复
背景描述中有些偏差,补充一下: 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

81,091

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧