ibatis2.3.4.726問題二
4063 ワード
仮定:
maping構成:
プログラム内のコード:
残念ながら、Objectクラスにid属性がないことが報告されます.why?
この問題は、ibatisが属性値を判断する際に、実行時に動的に設定されたオブジェクトから取得するのではなく、キャッシュから正確な構成クラス情報を直接取得するためです.
com.ibatis.common.beans.ComplexBeanProbeのコード:
com.ibatis.common.beans.ClassInfoでgetGetterTypeメソッド
解決策は、反射を使用して実際のオブジェクト情報を取得することです.
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;
}