S2Dao でバグ発見?
最近、仕事で S2Dao を使用していたのですが、バグらしきものを見つけました。
メソッドの戻り値型とエンティティ型が継承関係にある場合に、配列を返すメソッドの場合は正しく動作しないというものです。
たとえば、IWMember というインタフェースが存在し、そのインタフェースを実装したクラスのひとつとして Nono があるとします。
public interface IWMember { } public class Nono implements IWMember { }
このとき、DAO のメソッドとして、IWMember の配列を返すものがあったとします。
public interface Dao { // Dao が扱うエンティティは Nono とする public static final Class BEAN = Nono.class; // Nono のインタフェースである、IWMember の配列を返す DAO メソッド public IWMember[] selectWMembers(); }
上記のような場合に、selectWMembers の戻り値である IWMember[] へのマッピングに失敗します。
S2Dao のソースを追った結果、DaoMetaDataImpl 内で、ResultSet から JavaBean へのマッピングを行う ResultSetHandler の生成部に誤りがありました。
if (List.class.isAssignableFrom(method.getReturnType())) { return new BeanListMetaDataResultSetHandler(beanMetaData); } else if (isBeanClassAssignable(beanClass, method.getReturnType())) { return new BeanMetaDataResultSetHandler(beanMetaData); } else if (Array.newInstance(beanClass, 0).getClass() .isAssignableFrom(method.getReturnType())) { return new BeanArrayMetaDataResultSetHandler(beanMetaData); } else { return new ObjectResultSetHandler(); }
赤文字のぶぶんですが、isAssignableFrom の対象オブジェクトと引数のオブジェクトが逆になっていました。確認したのは、ちょっと古いソースだったのですが、最新版でも直っていないようです。
正しくは、下記のような指定ではないかと。
} else if (method.getReturnType() .isAssignableFrom(Array.newInstance(beanClass, 0).getClass())) { return new BeanArrayMetaDataResultSetHandler(beanMetaData); }
Class#isAssignableFrom の対象オブジェクトと引数の関係って私もいつも混乱します(w
System.out.println(Integer.valueOf(0) instaceof Numner); // true System.out.println(Number.class.isAssignableFrom(Integer.class)); // true
↑ですね。
S2Dao のバグってどこに報告したらよいんでしょうね・・・?