有两个PO类
在数据库中是Parent:1 to N Childclass Parent implements java.io.Serializable{    private String name;
    private Set child;...
}class Child implements java.io.Serializable{
    
    private String name;
    private Parent parent;
...
}在DAO中查询出多个Parent的List然后封装成Set<Parent> parent
把Set装入requestActionContext.getContext().put("parent", parent);
在页面中<s:iterator value="parent" status="stu">
    ${name}+${child.name}
</s:iterator>会出现这样的错误
javax.el.PropertyNotFoundException: Property 'parent' not found on type org.hibernate.collection.PersistentSet如果是<s:iterator value="parent" status="stu">
    ${name}+${child[stu.index].name}
</s:iterator>
则出现这样的错误
javax.el.PropertyNotFoundException: Property '0' not found on type org.hibernate.collection.PersistentSet请教各位,如何解决?如果是想遍历访问完parent,并把每个parent下的所有child访问完,该如何写呢?
<s:iterator>可不支持嵌套哦!

解决方案 »

  1.   

    修正你一个错误 , 你这里边 是EL表达式+struts2标签  根本没有 OGNL表达式 。不知道你下边这句话什么意思 , 还真没这么用过,你在Struts2里边配置这个Bean加上set get方法就可以了 还put什么 ???
    ActionContext.getContext().put("parent", parent);但你的错误是没有找到属性,不是表达式本身的错误。
    javax.el.PropertyNotFoundException: Property 'parent' not found on type org.hibernate.collection.PersistentSet
      

  2.   

    ActionContext.getContext().put("parent", parent); 这是放入request吗 ?????
      

  3.   

    确实是el表达式。
    我这里不是说EL的问题,而是怎么利用El取Set里的Set型对象的属性的值 的问题。ActionContext.getContext().put("parent", parent);是把parent对象放到request的Map中,以让页面取得该parent对象。<s:iterator value="parent" status="stu">
        ${name}
    </s:iterator>
    可以取到所需要的值,只是${child.name}或${child[stu.index].name}
    无法实现功能,请教各位我该怎么写才能实现我想要的功能?
      

  4.   

    <s:property value="name"/>
    你换成这样看
      

  5.   

    还有就是:假设class Parent implements java.io.Serializable{    private String name;
        private Set<Child> child = new HashSet<Child>();...
    }class Child implements java.io.Serializable{
        
        private String name;
        private Parent parent;
    ...
    }在Action中[code=Java]
    private Set<Parent> parent = new HashSet<Parent>();
    [/code]<input name="parent.makeNew[0].child.makeNew[0].amacContentName" type="text" value="xxx" size="10" />
    设不进去啊,提示
    Error setting value
    ognl.OgnlException: Error getting property descriptor: null
      

  6.   

    <s:iterator value="parent" id="pt" status="stu">
        <s:property value="#pt.name"/>
    </s:iterator>
    或者<s:iterator value="parent" status="stu">
        <s:property value="name"/>
    </s:iterator>
      

  7.   

    大家都没有明白我的意思,取parent中的name可以解决了,
    只是取child中的值(通过parent取,child在Parent中是Set,而传到页面的parent
    ActionContext.getContext().put("parent", parent);
    也是一个Set)却无法取出。<s:iterator>不支持嵌套,所以无法迭代取出child中的属性。
    同样地,也不知道怎么注入child的值。李刚的《Struts 2权威指南--基于WebWork核心的MVC开发》并没有讲到这种情况!
      

  8.   

    如果s:iterator真的不支持嵌套,那是否可以再用一个c:iterator来解决?
    我觉得,s:iterator不会不支持嵌套吧?
    我家里没有环境,明天到公司尝试一下再回复你。
      

  9.   

    s:iterator当然可以嵌套了:
    http://topic.csdn.net/u/20091201/22/18a199e5-dd45-48a6-a6c8-0e92bbe73bc1.html?seed=145740340&r=61576100#r_61576100
      

  10.   

    终于可以把值从页面设进Set属性对象中的Set属性中的元素里去了 方法如下: 
    第一:在页面这样写parent-1.1<input type="text" name="parent.makeNew[0].name">   
    parent-2.1<input type="text" name="parent.makeNew[1].name">   
    parent-2.1-child-1.1<input type="text" name="parent.makeNew[1].child.makeNew[0].name">   
    parent-2.1-child-1.2<input type="text" name="parent.makeNew[1].child.makeNew[1].name">在TestAction中    
    private Set<Parent> parent = new HashSet<Parent>(0);   
    getter and setter   
     建一个TestAction-conversion.properties与TestAction同在一个目录下KeyProperty_parent=name   
    Element_parent=com.test.Parent   
    CreateIfNull_parent=true在Parent中:private String name;      
    private Set<Child> child = new HashSet<Child>(0);   
      
    getter and setter   
    在Parent所在目录下: 
    建一个Parent-conversion.properties KeyProperty_child=name   
    Element_child=com.test.Child   
    CreateIfNull_child=true 这样就能注入了。 反过来,对于在页面取值,还在试验中。。
      

  11.   

    你上面那样的写法,只能是在知道Set中元素个数的时候才行。
    楼上也有人说了,s:iterator支持嵌套的,我也觉得这些个标签都支持嵌套的。
      

  12.   


    是的,makeNew[0]中的数字,可以通过一个index来设就可以了,页面有自带的index生成,具体怎么弄现在忘了。或者自定义一个js全局变量,引用一次后就+1,相信也可以达到效果
      

  13.   

    楼主,
    去弄本 李刚 的 《Struts2.1权威指南》参照书中5.5.2节
    也就是书中 P-172另外 hibernate 对于set集合 也是可以设置索引的
      

  14.   


    谢谢,其实我一直在参考这本书。必须承认,这几天我头脑不行了!
    诚如大家所言,s:iterator确实可以嵌套,我试了,确实能取得到,可能是此前我没有解决声明事务和OpenSessionInView而导致出现曲折。感谢大家的参与!
      

  15.   

    我把测试代码贴出来,供大家参考:
    Action中
    private Set<Email> emails = new HashSet<Email>(0);

    Email oneEmail1 = new Email();
    Personregiinfo onePersonregiinfo1 = new Personregiinfo();
    Set<Personregiinfo> personregiinfos = new HashSet<Personregiinfo>(0);
    onePersonregiinfo1.setPreiNickname("preiNickname1:");
    onePersonregiinfo1.setPreiId(1L);
    personregiinfos.add(onePersonregiinfo1);
    onePersonregiinfo1 = new Personregiinfo();
    onePersonregiinfo1.setPreiNickname("preiNickname2:");
    onePersonregiinfo1.setPreiId(2L);
    personregiinfos.add(onePersonregiinfo1);
    oneEmail1.setPersonregiinfos(personregiinfos);
    oneEmail1.setEmlName("emlName1");
    oneEmail1.setEmlDomainname("emlDomainname1");
    oneEmail1.setEmlId(1L);
    emails.add(oneEmail1);

    Email oneEmail2 = new Email();
    Personregiinfo onePersonregiinfo2 = new Personregiinfo();
    Set<Personregiinfo> personregiinfos2 = new HashSet<Personregiinfo>(0);
    onePersonregiinfo2.setPreiNickname("preiNickname2.1:");
    onePersonregiinfo2.setPreiId(3L);
    personregiinfos.add(onePersonregiinfo2);
    onePersonregiinfo2 = new Personregiinfo();
    onePersonregiinfo2.setPreiNickname("preiNickname2.2:");
    onePersonregiinfo2.setPreiId(4L);
    personregiinfos.add(onePersonregiinfo2);
    oneEmail2.setPersonregiinfos(personregiinfos2);
    oneEmail2.setEmlName("emlName2.1");
    oneEmail2.setEmlDomainname("emlDomainname2.1");
    oneEmail2.setEmlId(2L);
    emails.add(oneEmail2);。补充:这里我没有把手工把emails放到request的Map中,即没有写
    ActionContext.getContext().getSession().put("emails", emails);刚我又试了,加上上面的这句代码,一样可以运作。但是会不会有什么冲突或者存贮的范围(即不加上这句代码的话是把emails放在session中还是在request中)那就不知道了。还请高手指点迷津!!!!Email.java中。
    private Long emlId;
    private String emlName;
    private String emlDomainname;
    private Set<Personregiinfo> personregiinfos = new HashSet<Personregiinfo>(0);
    。Personregiinfo.java中。
    private Long preiId;
    private String preiNickname;。当然啦,这两个po类重载了equals()和hashCode()
    另外,Email-conversion.properties、XXXAction-conversion.properties和Personregiinfo-conversion.properties都参照前面的配有,不过不知道有没有影响到。jsp页面中:。
    <br>
    start<br>
    <s:iterator value="emails" status="stu">
        +${emlId}+${emlName}+${emlDomainname}
    <s:iterator value="personregiinfos" status="stu">
        +${preiId}+${preiNickname}
    </s:iterator>
    </s:iterator>
    <br>
    end

    最后,输出:start
    +1+emlName1+emlDomainname1 +1+preiNickname1: +2+preiNickname2: +3+preiNickname2.1: +4+preiNickname2.2: +2+emlName2.1+emlDomainname2.1 
    end
    问题到此得到解决了!再次感谢大家!
      

  16.   

    像这样定义在Action中的属性:
    ...
    private Set<Email> emails = new HashSet<Email>(0);
    ...
    Struts是自动把emails放在session中和request中,想修改存放范围,不知道怎么样来修改。好了,结贴了。
      

  17.   

    既然,你有《Struts2.1权威指南》
    那么你看看 P-97页。
    另外, 你说 Action 有个 emails 属性;然后,你再ActionContext中 put一个,这两个都是向request存对象其实,你这样,会有一个被覆盖掉的
    params拦截器 就是干这个事的,至于谁覆盖谁,没做过测试,不过你试试
    Action 中 String test = “action”;
    然后 ActionContext.put("test","ActionContext");
    然后,在页面 ${requestScope.test}看看是哪个。
    在补充:这里我没有把手工把emails放到request的Map中,即没有写 
    ActionContext.getContext().getSession().put("emails", emails); 
    你这样写的话 是往 session中存对象,不是request的!
    另外,既然你也再学习 Struts2.1 而且也用这本书的话
    帮我看看这个问题
    http://topic.csdn.net/u/20091225/10/bc6a364a-51b6-4241-90ff-6de38461fd63.html
      

  18.   

    嗯这里我贴错了,放在request中应该是
    ActionContext.getContext.put("emails", emails);你的问题我去看看。