Constructor injection type ambiguities in Spring

In Spring framework, when your class contains multiple constructors with same number of arguments, it will always cause the constructor injection argument type ambiguities issue.

Problem

Let’s see this customer bean example. It contains two constructor methods, both accept 3 arguments with different data type.


package com.mkyong.common;

public class Customer 
{
	private String name;
	private String address;
	private int age;
	
	public Customer(String name, String address, int age) {
		this.name = name;
		this.address = address;
		this.age = age;
	}
	
	public Customer(String name, int age, String address) {
		this.name = name;
		this.age = age;
		this.address = address;
	}
	//getter and setter methods
	public String toString(){
		return " name : " +name + "\n address : "
               + address + "\n age : " + age;
	}

}

In Spring bean configuration file, pass a ‘mkyong’ for name, ‘188’ for address and ’28’ for age.


<!--Spring-Customer.xml-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

	<bean id="CustomerBean" class="com.mkyong.common.Customer">

		<constructor-arg>
			<value>mkyong</value>
		</constructor-arg>
		
		<constructor-arg>
			<value>188</value>
		</constructor-arg>
		
		<constructor-arg>
			<value>28</value>
		</constructor-arg>
        </bean>

</beans>

Run it, what’s your expected result?


package com.mkyong.common;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App 
{
    public static void main( String[] args )
    {
    	ApplicationContext context = 
    	  new ClassPathXmlApplicationContext(new String[] {"Spring-Customer.xml"});

    	Customer cust = (Customer)context.getBean("CustomerBean");
    	System.out.println(cust);
    }
}

Output


 name : mkyong
 address : 28
 age : 188

The result is not what we expected, the second constructor is run, instead of the first constructor. In Spring, the argument type ‘188’ is capable convert to int, so Spring just convert it and take the second constructor, even you assume it should be a String.

In addition, if Spring can’t resolve which constructor to use, it will prompt following error message


constructor arguments specified but no matching constructor 
found in bean 'CustomerBean' (hint: specify index and/or 
type arguments for simple parameters to avoid type ambiguities)

Solution

To fix it, you should always specify the exact data type for constructor, via type attribute like this :


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

	<bean id="CustomerBean" class="com.mkyong.common.Customer">
	
		<constructor-arg type="java.lang.String">
			<value>mkyong</value>
		</constructor-arg>
		
		<constructor-arg type="java.lang.String">
			<value>188</value>
		</constructor-arg>
		
		<constructor-arg type="int">
			<value>28</value>
		</constructor-arg>
		
	</bean>

</beans>

Run it again, now you get what you expected.

Output

 name : mkyong
 address : 188
 age : 28
Note
It’s always a good practice to explicitly declared the data type for each constructor argument, to avoid constructor injection type ambiguities issue above.

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

avatar
16 Comment threads
3 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
16 Comment authors
PrashanthPratik GauravMohitshareefGeo Recent comment authors
newest oldest most voted
dililiq
Guest
dililiq

First running give me :
name : mkyong
address : 188
age : 28

and not ur result :
name : mkyong
address : 28
age : 188

Am-I rigth or wrong?

Shaswat
Guest
Shaswat

I got same as u…. !!!

Pratik Gaurav
Guest
Pratik Gaurav

How to deal with this situation since it’s overloaded and Arrays of Colors and Engine ?

public Car(String name, float price,String[] colors) {
super();
this.name = name;
this.price = price;
this.colors=colors;
}

/**
* @param name
* @param price
* @param engine
*/
public Car(String name, float price, Engine[] engine) {
super();
this.name = name;
this.price = price;
this.engine = engine;
}?

Mohit
Guest
Mohit

Can we use index while using constructor
DI to avoid ambiguity?

Prashanth
Guest
Prashanth

index is flexible to use

shareef
Guest
shareef

mkyong can you review my github here thanks its for spring tutorial tell me what you think and if you updated your source to update my github thanks

https://github.com/shareefhiasat/mkyong

sandeep
Guest
sandeep

this page of spring is supposed to align not able to see properly.

http://www.mkyong.com/spring/constructor-injection-type-ambiguities-in-spring/

And also give the link to download all the program after the explanation in some cases it is not available.

Thanks.

Jawahar
Guest
Jawahar

Really nice. Appreciate your efforts on this.

michael
Guest
michael

and can i do something like this:

public class person{
private man Man;

person(man Mann){
Man =Mann;
}

}
public class man{
}
<constructor-arg type="man" value="Gagan"></constructor-arg>
Gagan
Guest
Gagan

We can also use ‘index’ attribute for specifying the constructor.

    <constructor-arg type="java.lang.String" value="Gagan"></constructor-arg>
    <constructor-arg type="int" value="20" index="2"></constructor-arg>
    <constructor-arg type="java.lang.String" value="250" index="1"></constructor-arg>
yogesh prajapati
Guest
yogesh prajapati

each and every time while i run this example First Constructor is executed.

if i change sequence of constructors in POJO than always first constructor is executed.

Geo
Guest
Geo

Same here. No mater what, same output

Anand
Guest
Anand

Just perfect and was looking for. Terima Kasih Yong

Beniton
Guest
Beniton

Excellent Thank you very much

SpringLearner
Guest
SpringLearner

Good.

Rafael Morffi
Guest
Rafael Morffi

Excellent tutorials. Thank you very much!

trackback
Spring DI via constructor

[…] parameters, it will lead to common constructor injection type ambiguities issue, please read this solution.Download Source Code Download it – Spring-DI-constructor-example.zip (6KB) […]

trackback
Spring Tutorials | Tutorials

[…] Type Ambiguities Issue in Constructor injection The constructor injection argument type ambiguities issue is always happened in a bean which contains multiple constructor methods with many arguments. […]

trackback
Sport Wheelchair « Wheelchair Ramps

[…] Constructor injection type ambiguities in Spring | Spring […]