IMHO、最善の解決策は、commons- beanutilsを取り除き、SpringFrameworkorg.springframework.beans.PropertyAccessorFactoryを使用することです。
BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(targetObject);
wrapper.setAutoGrowNestedPaths(true);
動作の詳細については詳しく説明しませんが、確認したい場合は、上のリンクを参照してください。このAPIは非常に直感的ですが、SpringFrameworkCoreを構成する必要があります。クラスパスなので、この機能のためだけにSpringを追加することはお勧めしません。
ただし、
味方としてcommons-beanutilsしかない場合、次のコードスニペットは、値を設定するときにネストされたパスを拡張するのに役立つ可能性があります。したがって、パスプロパティに沿ったnullオブジェクトについて心配する必要はありません。
この例では、JPAタプルクエリを使用して、対応する値を設定する特定のプロパティパスを持つカスタムオブジェクトを作成しました。
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Tuple;
import javax.persistence.TupleElement;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.expression.DefaultResolver;
public class TupleToObject<T> {
public List<T> transformResult(List<Tuple> result, Class<T> targetClass) {
try {
List<T> objects = new ArrayList<>();
for (Tuple tuple : result) {
T target = targetClass.newInstance();
List<TupleElement<?>> elements = tuple.getElements();
for (TupleElement<?> tupleElement : elements) {
String alias = tupleElement.getAlias();
Object value = tuple.get(alias);
if (value != null) {
instantiateObject(target, alias);
PropertyUtils.setNestedProperty(target, alias, value);
}
}
objects.add(target);
}
return objects;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void instantiateObject(T target, String propertyPath) throws Exception {
DefaultResolver resolver = new DefaultResolver();
Object currentTarget = target;
while (resolver.hasNested(propertyPath)) {
final String property = resolver.next(propertyPath);
Object value = PropertyUtils.getSimpleProperty(currentTarget, property);
if (value == null) {
Class<?> propertyType = PropertyUtils.getPropertyType(currentTarget, property);
value = propertyType.newInstance();
PropertyUtils.setSimpleProperty(currentTarget, property, value);
}
currentTarget = value;
propertyPath = resolver.remove(propertyPath);
}
}
}
このコードはcommons-beanutils-1.9.3.jarを使用しています