0

BeanProcessor を使用してクラスにデータを入力しようとしていますが、部分的に機能します。私のクラスは次のとおりです

アドレスクラス

public class Address {

    ..All attributes of address class go here...
        .. All setter and getters go here...
}

address クラスをメンバとして持つ Employee クラス

public class Employee {

    private int ID;
    private String fname;
    private String lname;
    private String mobile;
    private String phone;
    private String email;
    private String position;
    private String title;
        private String username;
        private String password;
        private String question;
        private String answer;
        private Address address;          << address class is a member of employee class
        .. All setter and getters go here....
}

私のモデルは次のとおりです。

        Employee emp = new Employee();
        try {

            ps = con.prepareStatement("select * from employee,address "
                    + "WHERE employee.username = ? AND "
                    + "employee.AddID = address.ID");

            ps.setString(1, username);
            ResultSet r = ps.executeQuery();
            if (r.next()) {
                BeanProcessor bp = new BeanProcessor();
                emp = bp.toBean(r,Employee.class);
                System.out.println("name:" + emp.getName()); << shows the name correctly
                System.out.println("block:"+emp.getAddress().getBlock());<< the output is null
            }

            con.close();
            ps.close();
        } catch (SQLException e) {
            System.err.println(e.getMessage());

        }
       return emp;
    }

アプリケーションを実行すると、emp オブジェクトは正しく取り込まれているが、その中の Address オブジェクトは正しく取り込まれていないことが示され、getBlock() メソッドに対して null が返されます。データベース ブロックに値があることを確認しました。スピリットウォーカーの答えによると、nullpointer例外をスローしていないため、変換は正しく行われます.それが間違っている場合、BeanProcessorの代替としてのあなたの提案は何ですか?

4

2 に答える 2

1

対応する住所レコードのブロック列にデータがあることを確認できますか? 出力がNullPointerExceptionではなくnullであると言ったため、このように考えることができます。これは、アドレスが BeanProcessor によって適切にマップおよび初期化されていることを意味します。 () は NPE になりますか?

また、BeanProcessor JAVA doc によると ** 変換が失敗した場合 (つまり、プロパティが int で列が Timestamp だった場合)、SQLException がスローされます**。変換に問題があるようには見えません。

于 2013-02-20T05:54:49.350 に答える
1

BeanProcessorのドキュメントから:

ResultSet 行を JavaBean に変換します。この実装では、リフレクションおよび BeanInfo クラスを使用して、列名を Bean プロパティ名に一致させます。プロパティは、いくつかの要因に基づいて列に一致します。

  1. クラスには、列と同じ名前の書き込み可能なプロパティがあります。名前の比較では大文字と小文字が区別されません。
  2. 列の型は、ResultSet.get* メソッドを使用して、プロパティの set メソッド パラメーターの型に変換できます。変換が失敗した場合 (つまり、プロパティが int で列がタイムスタンプであった場合)、SQLException がスローされます。

2番目の点に注意してください。AddressResultSet はクラスをサポートしていません。したがって、BeanProcessor はこのタイプのフィールドを処理できません。

UPDATE:処理中の SQLException について。

SQLクエリを確認する必要があります。名前付きの列を返さない場合address、BeanProcessor はこのプロパティに触れないため、例外をスローしません。

更新: NullPointerException について。

getAddress().getBlock()はい、 NullPointerException をスローしないのは奇妙に思えます。しかし、上記のドキュメントから、BeanProcessor がアドレス フィールドを適切に初期化できないことは明らかです。私の推測では、呼び出しgetAddress()がなくても何らかの形で非 null オブジェクトが返されると思いsetAddressます。Employee のデフォルトのコンストラクタとgetAddressメソッドを再確認してください。

new Employee().getAddress().getBlock()これを確認するために電話することもできます。

更新:ネストされたオブジェクトの処理を実装する方法

BeanProcessor の経験はありませんが、使用できる保護されたメソッドがいくつか提供されています。たとえば、processColumnをオーバーライドしてみることができます:

public class CustomBeanProcessor extends BeanProcessor {

    @Override
    protected  int[] mapColumnsToProperties(ResultSetMetaData rsmd, PropertyDescriptor[] props) throws SQLException {
          int[] mapping = super.mapColumnsToProperties(rsmd, props);
          for(PropertyDescriptor prop : props) {
                //find address property
                //change PROPERTY_NOT_FOUND value to index of column (addressid maybe)
          }
    }

    @Override
    protected Object processColumn(ResultSet rs, int index, Class<?> propType) throws SQLException {
        if(propType==Address.class) {
            //here you create address object
            //you may need several calls to rs.get to check for all address properties.
        }
    }
}
于 2013-02-20T05:50:56.483 に答える