spring-projects/spring-framework · error · IllegalArgumentException
Specify either 'targetObject' or 'targetBeanName', not both
Error message
Specify either 'targetObject' or 'targetBeanName', not both
What it means
Thrown by PropertyPathFactoryBean.setBeanFactory() when both targetObject (an inline/instance target) and targetBeanName (a named target) have been configured. PropertyPathFactoryBean evaluates a property path on exactly one target; specifying both is ambiguous, so Spring rejects it at the BeanFactory-aware stage.
Solutions
- Keep only one: use targetBeanName for a named bean reference, or targetObject for an inline/inner bean.
- Prefer targetBeanName with a singleton target so Spring can eagerly resolve and determine the result type.
- In code, delete whichever setTargetObject/setTargetBeanName call is unwanted.
Example fix
<!-- before (broken): both set --> <bean class="...PropertyPathFactoryBean"> <property name="targetObject" ref="tb"/> <property name="targetBeanName" value="tb"/> <property name="propertyPath" value="age"/> </bean> <!-- after --> <bean class="...PropertyPathFactoryBean"> <property name="targetBeanName" value="tb"/> <property name="propertyPath" value="age"/> </bean>
Defensive patterns
Strategy: validation
Validate before calling
if (fb.getTargetObject() != null && /* targetBeanName set */ targetBeanName != null) {
throw new IllegalStateException("Choose targetObject OR targetBeanName, not both");
} Type guard
static boolean hasSingleTarget(PropertyPathFactoryBean fb, String targetBeanName) {
return (fb.getTargetObject() == null) ^ (targetBeanName == null);
} Try / catch
try {
fb.setBeanFactory(beanFactory);
} catch (IllegalArgumentException ex) {
if (ex.getMessage().contains("not both")) {
// drop one of the two targets and retry
}
throw ex;
} Prevention
- Decide on one style (bean-name ref vs inline object) and document it for the team.
- Review PropertyPathFactoryBean definitions in code review for duplicate target properties.
- Prefer targetBeanName for named singletons so Spring can resolve the result type eagerly.
When it happens
Trigger: XML with both <property name="targetObject" ref="..."> and <property name="targetBeanName" value="..."> on the same PropertyPathFactoryBean. Programmatic calls to setTargetObject(...) and setTargetBeanName(...).
Common situations: Copy-paste from two examples merging both properties. Refactoring from inline bean to bean-name reference and forgetting to remove the old property. Confusion about which form to use.
Related errors
- Neither 'targetObject' nor 'targetBeanName' specified, and…
- 'propertyPath' is required
- Specify 'targetObject' or 'targetBeanName' in combination…
- Property 'serviceLocatorInterface' is required
- ServiceLocatorFactoryBean needs to run in a BeanFactory…
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/4325d293f5b00989.
Report an issue: GitHub.
Appendix: source
Thrown at spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyPathFactoryBean.java:164
/**
* The bean name of this PropertyPathFactoryBean will be interpreted
* as "beanName.property" pattern, if neither "targetObject" nor
* "targetBeanName" nor "propertyPath" have been specified.
* This allows for concise bean definitions with just an id/name.
*/
@Override
public void setBeanName(String beanName) {
this.beanName = StringUtils.trimAllWhitespace(BeanFactoryUtils.originalBeanName(beanName));
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
String targetBeanName = this.targetBeanName;
if (this.targetBeanWrapper != null && targetBeanName != null) {
throw new IllegalArgumentException("Specify either 'targetObject' or 'targetBeanName', not both");
}
if (this.targetBeanWrapper == null && targetBeanName == null) {
if (this.propertyPath != null) {
throw new IllegalArgumentException(
"Specify 'targetObject' or 'targetBeanName' in combination with 'propertyPath'");
}
// No other properties specified: check bean name.
int dotIndex;
if (this.beanName == null || (dotIndex = this.beanName.indexOf('.')) <= 0) {
throw new IllegalArgumentException(
"Neither 'targetObject' nor 'targetBeanName' specified, and PropertyPathFactoryBean " +
"bean name '" + this.beanName + "' does not follow 'beanName.property' syntax");
}
targetBeanName = this.beanName.substring(0, dotIndex);
this.targetBeanName = targetBeanName;
this.propertyPath = this.beanName.substring(dotIndex + 1);View on GitHub (pinned to 69bf83ad71)