2006年06月18日 [長年日記]
_ [Seasar] S2Dxoのバグ?
きむきむさんのところでS2Dxoが 怒涛のコミットをしているようで、正式リリース前だけどいろいろ試してみている。
で、こんなテストを書くと、なぜか失敗してしまう。
Src src = new Src(); src.setSrcSub1(new SrcSub1()); src.setId("001"); src.setName("momo"); src.getSrcSub1().setSubId("002"); src.getSrcSub1().setSubName("submomo"); Desc desc = (Desc) basicDxo.convert(src, Desc.class); assertEquals("001", desc.getId()); assertEquals("momo", desc.getName()); assertEquals("002", desc.getSubId()); assertEquals("submomo", desc.getSubName());
desc.getIdがnullになってしまうのだ。
ほとんど同じようなテストは通っているので、 おかしいなぁと思って真剣にデバッグしてみたら なんだかS2Dxoのバグ?っぽいものがあったのでクイックハックしてみた。
>svn diff Index: src/main/java/org/seasar/dxo/meta/impl/DxoMetaDataFactoryImpl.java =================================================================== --- src/main/java/org/seasar/dxo/meta/impl/DxoMetaDataFactoryImpl.java (リビジョン 31) +++ src/main/java/org/seasar/dxo/meta/impl/DxoMetaDataFactoryImpl.java (作業コピー) @@ -36,7 +36,7 @@ if (dxoMetaDataCache.containsKey(dxoClass)) { return (DxoMetaData) dxoMetaDataCache.get(dxoClass); } - AnnotationReader annotationReader = annotationReaderFactory.createDxoAnnotationReader(dxoClass); + AnnotationReader annotationReader = annotationReaderFactory.createDxoAnnotationReader(); DxoMetaData metaData = new DxoMetaDataImpl(dxoClass, annotationReader); dxoMetaDataCache.put(dxoClass, metaData); return metaData; Index: src/main/java/org/seasar/dxo/converter/impl/BeanConverter.java =================================================================== --- src/main/java/org/seasar/dxo/converter/impl/BeanConverter.java (リビジョン 31) +++ src/main/java/org/seasar/dxo/converter/impl/BeanConverter.java (作業コピー) @@ -16,6 +16,9 @@ package org.seasar.dxo.converter.impl; import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import org.seasar.dxo.converter.Converter; import org.seasar.dxo.converter.ConverterFactory; @@ -99,18 +102,26 @@ protected Object getValue(String propertyName, Object source) { BeanDesc beanDesc = BeanDescFactory.getBeanDesc(source.getClass()); + List subBeanDescs = new ArrayList(); for (int i = 0; i < beanDesc.getPropertyDescSize(); i++) { PropertyDesc sourcePropertyDesc = beanDesc.getPropertyDesc(i); if (sourcePropertyDesc.hasReadMethod() == false) { continue; } if (isBasicType(sourcePropertyDesc.getPropertyType()) == false) { - return getValue(propertyName, sourcePropertyDesc.getValue(source)); + subBeanDescs.add(sourcePropertyDesc); } if (sourcePropertyDesc.getPropertyName().equalsIgnoreCase(propertyName)) { return sourcePropertyDesc.getValue(source); } } + for (Iterator it = subBeanDescs.iterator(); it.hasNext();) { + try { + PropertyDesc sourcePropertyDesc = (PropertyDesc) it.next(); + return getValue(propertyName, sourcePropertyDesc.getValue(source)); + } catch (ReadMethodNotFoundException e) { + } + } throw new ReadMethodNotFoundException(beanDesc.getBeanClass(), propertyName); } Index: src/main/resources/s2dxo.dicon =================================================================== --- src/main/resources/s2dxo.dicon (リビジョン 31) +++ src/main/resources/s2dxo.dicon (作業コピー) @@ -9,5 +9,5 @@ <component class="org.seasar.dxo.converter.impl.ConverterFactoryImpl"/> <component class="org.seasar.dxo.deployer.DxoDeployer"/> <component class="org.seasar.dxo.meta.impl.DxoMetaDataFactoryImpl"/> - <component class="org.seasar.dxo.annotation.impl.FieldAnnotationReaderFactory"/> + <component class="org.seasar.dxo.annotation.impl.AnnotationReaderFactoryImpl"/> </components>
s2dxo.diconとDxoMetaDataFactoryImpl.javaの修正はコンパイルエラーを 取っただけなので本質じゃない。 BeanConverter.getValueを少し直した。 毎回Listを生成しているあたり効率が悪そうなんだけど、 とりあえずこれで先ほどのテストケースは通った。
パッチ取り込みました。ありがとうございます。m(_ _)m
確認しました。<br>テストケースもそのまま使ってくれたんですね。<br>これなら、私の作ったテストケースを全文載せればよかったですね…(^^;