• 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に詰め替える方法を用いることにしました。

  • 相关阅读:
    JS: 子项可以来回交换的两个下拉列表
    DOM事件
    DOM基础2——元素
    DOM基础1
    JS: 随机点名程序与万年历
    G_S男女匹配算法(算法的第一个程序2016.09.19)
    Java IO流详尽解析(大神之作)
    细讲解JAVA中的IO流
    c++运算符的优先级(收好不谢)
    java程序——输出当月日历表
  • 原文地址:https://www.cnblogs.com/aggavara/p/2708712.html
Copyright © 2020-2023  润新知