2013-02-20 45 views
0

我想使用BeanProcessor填充我的类,但它部分工作。 我的课是如下BeanProcessor部分工作

ADDRES类

public class Address { 

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

员工具有地址类作为其成员

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,我检查了数据库块有一个值。根据spiritwalker的回答吹,因为它不是抛出空指针异常转换完成correclty,如果这是错误的,你有什么建议作为BeanProcessor的替代?

+0

NPE是一个公平的问题。你可以检查当你调用'(new Employee())时会发生什么。getAddress()。getBlock();'? – 2013-02-20 06:12:50

回答

0

BeanProcessor documentation

转换一个结果行插入一个JavaBean。此实现使用反射和BeanInfo类将列名称与bean属性名称进行匹配。属性根据几个因素与列匹配:

  1. 该类具有一个与列名称相同的可写属性。名称比较不区分大小写。
  2. 使用ResultSet.get *方法可以将列类型转换为属性的设置方法 参数类型。如果转换失败 (即属性是int并且列是时间戳),则抛出一个 SQLException。

注意第二点。 ResultSet不支持Address类。所以,BeanProcessor不能处理这种类型的字段。

更新:关于处理期间的SQLException。

你应该检查你的sql查询。如果它不返回名为address的列,那么BeanProcessor不会触及此属性,因此不会抛出任何异常。

更新:关于NullPointerException。

是的,听起来很奇怪,getAddress().getBlock()不会抛出NullPointerException。但从上面的文档中可以明显看出,BeanProcessor无法正确初始化地址字段。我的猜测是,即使没有setAddress调用,getAddress()也会以某种方式返回非空对象。请仔细检查员工的默认构造函数和getAddress方法。

您也可以致电new Employee().getAddress().getBlock()进行检查。

UPDATE:如何实现嵌套的对象处理

我没有与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. 
     } 
    } 
} 
+0

那我该怎么做? – 2013-02-20 05:52:25

+0

这是一个更广泛的问题。 BeanProcessor只能处理标准类型,因此不支持嵌套的Bean。因此,您可以尝试使用非嵌套的普通bean(例如,直接在员工类中的块名称)来增强查询和/或Bean以仅读取标准类型。您也可以尝试分开处理地址和员工,然后以某种方式将它们链接在一起。 Google查询将我带到[类似主题的讨论](http://apache-commons.680414.n4.nabble.com/Commons-Dbutils-Request-feedback-for-possible-patch-handling-nested-beans-td734323 .html) – 2013-02-20 05:57:51

+0

我想推荐你查看[JPA](http://www.oracle.com/technetwork/java/javaee/tech/persistence-jsp-140049.html),而不是实现你自己的ORM框架。 – 2013-02-20 06:01:14

1

可以确保相应的地址记录确实有列数据?它使这样想,因为,你说输出为空而不是NullPointerException这意味着该地址已被BeanProcessor正确映射和初始化,否则emp.getAddress()应该为您提供一个空值,然后emp.getAddress ().getBlock()将最终与NPE?

而且,根据BeanProcessor JAVA doc **如果转换失败(即属性是int并且列是Timestamp),则SQLException是throw **,它看起来不像是什么错转换。