Skip to content

Support option for @Argument binding to fall back on direct field access  #599

Closed
@sataphat

Description

@sataphat

Sometimes, the class to use as the target for @Argument might not have a setter for all its properties. E.g.

public class PriceValuation4 {
    // ...
    protected List<ActiveOrHistoricCurrencyAndAmount> ttlNAV;
    protected List<UnitPrice15> pricDtls;
    protected List<ValuationStatistics3> valtnSttstcs;
    // ...
    public PriceValuation4 addTtlNAV(ActiveOrHistoricCurrencyAndAmount ttlNAV) {
        this.getTtlNAV().add(ttlNAV);
        return this;
    }

    public PriceValuation4 addPricDtls(UnitPrice15 pricDtls) {
        this.getPricDtls().add(pricDtls);
        return this;
    }

    public PriceValuation4 addValtnSttstcs(ValuationStatistics3 valtnSttstcs) {
        this.getValtnSttstcs().add(valtnSttstcs);
        return this;
    }
}

Especially when the class is from a third-party library, which is my case here.

Is it possible to fall back to using the direct-field-access approach when the proper Setter cannot be found?

Would the following code change make sense?

From:
https://github.com/spring-projects/spring-graphql/blob/main/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlArgumentBinder.java#L300

public class GraphQlArgumentBinder {
	// ...

	private Object bindMapToObjectViaSetters(
			Map<String, Object> rawMap, Constructor<?> constructor, ResolvableType ownerType,
			ArgumentsBindingResult bindingResult) {

		Object target = BeanUtils.instantiateClass(constructor);
		BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(target);

		for (Map.Entry<String, Object> entry : rawMap.entrySet()) {
		// ...
		}
	}        
}

To:

import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper;

public class GraphQlArgumentBinder {
	// ...

	private Object bindMapToObjectViaSetters(
			Map<String, Object> rawMap, Constructor<?> constructor, ResolvableType ownerType,
			ArgumentsBindingResult bindingResult) {

		Object target = BeanUtils.instantiateClass(constructor);
		/*========================================================================*/
		DirectFieldAccessFallbackBeanWrapper beanWrapper = new DirectFieldAccessFallbackBeanWrapper(target);
		/*========================================================================*/

		for (Map.Entry<String, Object> entry : rawMap.entrySet()) {
		// ...
		}
	}        
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions