ibatis2.3.4.726問題二

4063 ワード

仮定:

public class Account {

	private Integer id;
	private String firstName;
	private String lastName;
	private String emailAddress;
        // Object 
	private Object primaryKey;
        //....
}

maping構成:

<select id="selectAccount" parameterClass="Account" resultMap="AccountResult">
select
  ACC_ID ,
  ACC_FIRST_NAME ,
  ACC_LAST_NAME ,
  ACC_EMAIL 
from ACCOUNT 
<dynamic prepend="where">
	<isEqual property="primaryKey.id" prepend="and" compareValue="1">
		ACC_ID = 2
	</isEqual>
</dynamic>
</select>

プログラム内のコード:

Account a = new Account();
Account a2 = new Account();
a2.setId(new Integer(1));
a.setPrimaryKey(a2);

List list = (List) sqlMapper.queryForList("selectAccount", a);

残念ながら、Objectクラスにid属性がないことが報告されます.why?
この問題は、ibatisが属性値を判断する際に、実行時に動的に設定されたオブジェクトから取得するのではなく、キャッシュから正確な構成クラス情報を直接取得するためです.
com.ibatis.common.beans.ComplexBeanProbeのコード:

  public Class getPropertyTypeForGetter(Object object, String name) {
    Class type = object.getClass();

    if (object instanceof Class) {
      type = getClassPropertyTypeForGetter((Class) object, name);
    } else if (object instanceof Map) {
      Map map = (Map) object;
      Object value = map.get(name);
      if (value == null) {
        type = Object.class;
      } else {
        type = value.getClass();
      }
    } else {
      if (name.indexOf('.') > -1) {
        StringTokenizer parser = new StringTokenizer(name, ".");
        while (parser.hasMoreTokens()) {
          name = parser.nextToken();
          // type 
          type = ClassInfo.getInstance(type).getGetterType(name);
        }
      } else {
        type = ClassInfo.getInstance(type).getGetterType(name);
      }
    }

    return type;
  }

com.ibatis.common.beans.ClassInfoでgetGetterTypeメソッド

  public Class getGetterType(String propertyName) {
    Class clazz = (Class) getTypes.get(propertyName);
    if (clazz == null) {
      throw new ProbeException("There is no READABLE property named '" + propertyName + "' in class '" + className + "'");
    }
    return clazz;
  }

解決策は、反射を使用して実際のオブジェクト情報を取得することです.

  public Class getPropertyTypeForSetter(Object object, String name) {
    Class type = object.getClass();

    if (object instanceof Class) {
      type = getClassPropertyTypeForSetter((Class) object, name);
    } else if (object instanceof Map) {
      Map map = (Map) object;
      Object value = map.get(name);
      if (value == null) {
        type = Object.class;
      } else {
        type = value.getClass();
      }
    } else {
      if (name.indexOf('.') > -1) {
        // StringTokenizer , 。
        // , 
      	String[] names = name.split("\\."); 
		for (int i = 0; i < names.length; ++i) {
			try {
				Method method = ClassInfo.getInstance(type).getGetter(names[i]);
				object = method.invoke(object, new Object[]{});
				if (object != null) {
					type = object.getClass();
				} else {
					type = null;
					break;
				}
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
      } else {
        type = ClassInfo.getInstance(type).getSetterType(name);
      }
    }

    return type;
  }