• SAStruts/S2JDBC ネストしたプロパティの画面部品


    SAStruts/S2JDBC JSPで画面部品を作ってみる - 130単位

    の続きです。

    実際に作りたかった画面部品は、テーブル結合を伴った、ネストしたプロパティを持つ項目でした。これを実現するのにまた地味に時間を食いました。というか要はMapの使い方を知らなかっただけなのですが。

    エンティティとサービス

    従業員に部署を結合して、所属する部署を表示させたいとします。

    Employeeへ関連を定義します。

    @Entity
    public class Employee {
        ...
        @ManyToOne
        Department department;
    }
    

    EmployeeServiceで、結合して取得するようにします。findAll()をオーバーライドしてます。

    public class EmployeeService extends AbstractService<Employee> {
        ...
        @Override
        public List<Employee> findAll() {
            return select()
                .innerJoin(department())
                .orderBy(asc(id()))
                .getResultList();
    }
    

    JSP

    さて、前回ようなJSPに単に追加しただけでは、ネストしたプロパティアクセスしようとするとエラーが起きます。

    <html:option value="${e.jgjycd}">${e.id} ${e.name} (${e.department.name})</html:option>
    
    javax.el.PropertyNotFoundException: Property 'name' not found on type test.entity.Department
    

    employeeはBeanMapになっていても、departmentがBeanMapではないためです。employeeのみにBeans#createAndCopy()を実行しただけでは、departmentというプロパティはできなくなっているようです。ひがさんの少し前の記事にも、「ネストしたプロパティは対象外」と書かれています。

    そこで、employeeをMapに詰め替えてListを構築する際に、departmentも同様にMapにしてやる必要があります。Mapに値を追加するには、「put(key, value)」を使います。

    <%
        /* インポート等省略 */
        List<Employee> employeeList = employeeService.findAll();
        List<BeanMap> employeeItems = new ArrayList<BeanMap>();
    
        for (Employee employee : employeeList) {
            BeanMap empMap = Beans.createAndCopy(BeanMap.class, employee).execute();
            BeanMap deptMap = Beans.createAndCopy(BeanMap.class, employee.department).execute();
    
            empMap.put("department", deptMap);
            employeeItems.add(empMap);
        }
    %>
    <html:select property="searchLectureCd">
        <html:option value=""></html:option>
        <c:forEach var="e" items="${jgyofpItems}">
        <html:option value="${e.jgjycd}">${e.id}  ${e.name} (${e.department.name})</html:option>
        </c:forEach>
    </html:select>
    
    ちなみに

    最初は下記のようにやろうとしてました。

    empMap.department = deptMap;
    

    もろにPHP(の連想配列)の影響なわけですが、これではダメですね。

    サービスでMap取得 (失敗例)

    そもそも「最初からサービスでMapを返せばいいんじゃないの」と思い、以下を試してみました。

    public class EmployeeService extends AbstractService<Employee> {
        ...
        public List<BeanMap> findAllMap() {
            return jdbcManager
                .from(BeanMap.class)
                .orderBy(asc(id()))
                .getResultList();
        }
    }
    

    しかし結果は失敗。問い合わせ実行時に例外が発生します。

    org.seasar.extension.jdbc.exception.NonEntityRuntimeException: [ESSR0704](org.seasar.framework.beans.util.BeanMap)はエンティティではありません。
    

    Eclipse上ではエラーになりませんでしたし、SQLによる照会のselectBySql()だとMapで返せるようなので、いけるかと思ったのですが。AbstractServiceのジェネリクスでエンティティが指定されているのが関係してそうですが、今の自分の知識量ではこのくらいの推測が限界です。

    というわけで、素直にJSPでMapに詰め替える方法を用いることにしました。

  • 相关阅读:
    【AS3代码】类的分包
    语句include和require的区别是什么?
    php创建多级目录的函数
    【AS3代码】打砖块
    【AS3代码】弧度的转换
    【AS3代码】是男人就坚持30秒
    每天问女儿的四个问题
    PowerDesigner16生成SQL2005列注释
    做分析师=盖房子【转】
    用gephi自动分析网站链接方式
  • 原文地址:https://www.cnblogs.com/aggavara/p/2708712.html
Copyright © 2020-2023  润新知