I'm new to mapstruct. I'm trying to map ItemInfo
to Item
object and the following are my classes.
public class ItemInfo {
private String itemOwner;
private String itemOwnerArea;
//getters and setters
}
Following is the class that I'm planing to convert to
public class Item {
private UserInfo owner;
// getters and setters.
}
UserInfo class (Note that it has two constructors)
public class UserInfo {
private final String username;
private final String area;
public UserInfo(String username, String area){
//set
}
public UserInfo(String info) {
//set
}
// getters only
}
I have created the mapper interface as below
@Mapper
public interface ItemMapper {
ItemMapper INSTANCE = Mappers.getMapper(ItemMapper.class);
@Mapping(source = "itemOwner", target = "owner.username")
@Mapping(source = "itemOwnerArea", target = "owner.area")
Item mapItemInfoToItem(ItemInfo itemInfo);
}
When I build this, I get the following error
Ambiguous constructors found for creating com.app.test.UserInfo. Either declare parameterless
constructor or annotate the default constructor with an annotation named @Default.
Can you guide me please?
Update.
As mentioned by @AnishB I added a default constructor but I get a different error
Property "username" has no write accessor in UserInfo for target name "owner.username".
Thanks
We are working on improving the error message in this place.
From the current error message
Ambiguous constructors found for creating
com.app.test.UserInfo
. Either declare parameterless constructor or annotate the default constructor with an annotation named@Default
.
You have 2 options:
@Default
annotation and annotate the default constructor that MapStruct should use. I would highly recommend this approach.MapStruct is not shipping this annotation because it is focused on bean mapping and doesn't want to pollute the entity code with annotations from MapStruct.
Therefore it can use any Default
annotation from any package.
e.g.
package foo.support.mapstruct;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.CLASS)
public @interface Default {
}
You already did that and the next error message:
Property "username" has no write accessor in UserInfo for target name "owner.username".
Is there saying that there is no write accessor for the username, because most likely you have annotated the single parameter constructor. If you've done that then MapStruct only knows about the area
and not about the username
. Another option for that error is that you have added an empty parameterless constructor and no setters.
You most likely need
@Default
public UserInfo(String username, String area){
//set
}
Mapstruct needs a default empty constructor for its functioning.
So, update the UserInfo class to have a default empty constructor:
public class UserInfo {
private final String username;
private final String area;
public UserInfo(){
}
public UserInfo(String username, String area){
//set
}
public UserInfo(String info) {
//set
}
// setters and getters
}
Or annotate anyone constructor with @Default
so that mapstruct can use that constructor as a default constructor.
For example :
@Default
public UserInfo(String info) {
//set
}
Also, you have to add setters in UserInfo as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With