I'm facing NumberFormatException when Converting DTO to Entity. Though the field on which I'm getting that exception is String in both DTO and Entity.
And the weird thing is I'm getting that exception only when I deploy my application on docker, If I run my application as standalone then everything is fine.
Below is my code
UserDTO:
@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserDto {
private Integer userId;
private String displayCode;
private String firstName;
private String lastName;
private String username;
private String password;
private String email;
private String phone;
private String photo;
private Short title;
private String npi;
private List<Integer> postNominal;
@JsonProperty("isDoctor")
private Boolean isDoctor;
private Integer userType;
private Boolean active;
private Boolean agreementActive;
private String accessCode;
private Integer createdBy;
private Timestamp createdTimestamp;
private Integer updatedBy;
private Timestamp updatedTimestamp;
private List<RoleDto> roles;
private Integer departmentId;
private UserDto reportingTo;
@JsonIgnore
private String partnerDisplayCode;
@JsonProperty("userRoles")
private String userRole;
private String base64Image;
getters...
setters...
}
UserEntity:
@Entity
@Table(name = "user", schema = "user_management")
public class UserEntity extends BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Integer userId;
@Column(name = "display_code")
private String displayCode;
@Column(name = "user_type")
private Short userType;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "username")
private String username;
@Column(name = "password")
private String password;
@Column(name = "email")
private String email;
@Column(name = "phone")
private String phone;
@Column(name = "photo")
private String photo;
@Column(name = "title")
private Short title;
@Column(name = "npi")
private String npi;
@Column(name = "department_id")
private Integer departmentId;
@Column(name = "is_doctor")
private Short isDoctor;
@Column(name = "agreement_active")
private Short agreementActive;
@Column(name = "access_code")
private String accessCode;
@Column(name = "status")
private Short active;
getters ....
setters
}
UserService Class:
@Override
@Transactional
public UserDto persist(UserWithDependenciesDto user) {
modelMapper.getConfiguration().setSkipNullEnabled(true);
modelMapper.addConverter(CommonUtil.BOOLEAN_SHORT_CONVERTER);
UserEntity userEntity = modelMapper.map(user.getUser(), UserEntity.class);
....
}
@PostConstruct
public void initializeModelMapperStrategy() {
this.modelMapper.getConfiguration().setAmbiguityIgnored(true);
this.modelMapper.getConfiguration()
.setMatchingStrategy(MatchingStrategies.STRICT);
}
UserWithDependenciesDto:
public class UserWithDependenciesDto {
@JsonProperty("partnerId")
private Integer partnerId;
@JsonProperty("user")
private UserDto user;
@JsonProperty("createdBy")
private Integer createdBy;
....
}
Exception:
org.modelmapper.MappingException: ModelMapper mapping errors:
nglis-usrm-api_1 |
nglis-usrm-api_1 | 1) Converter org.modelmapper.internal.converter.NumberConverter@e822ec7
failed to convert java.lang.String to java.lang.Integer.
nglis-usrm-api_1 | Caused by: org.modelmapper.MappingException: ModelMapper mapping errors:
nglis-usrm-api_1 |
nglis-usrm-api_1 | 1) Error mapping AJ01 to java.lang.Integer
nglis-usrm-api_1 |
nglis-usrm-api_1 | 1 error
nglis-usrm-api_1 | at
org.modelmapper.internal.Errors.toMappingException(Errors.java:258)
nglis-usrm-api_1 | at
org.modelmapper.internal.converter.NumberConverter.numberFor(NumberConverter.java:181)
nglis-usrm-api_1 | at
org.modelmapper.internal.converter.NumberConverter.convert(NumberConverter.java:75)
nglis-usrm-api_1 | at
org.modelmapper.internal.converter.NumberConverter.convert(NumberConverter.java:57)
nglis-usrm-api_1 | at
org.modelmapper.internal.MappingEngineImpl.convert(MappingEngineImpl.java:303)
nglis-usrm-api_1 | at
org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:110)
nglis-usrm-api_1 | at
org.modelmapper.internal.MappingEngineImpl.setDestinationValue(MappingEngineImpl.java:242)
nglis-usrm-api_1 | at
org.modelmapper.internal.MappingEngineImpl.propertyMap(MappingEngineImpl.java:188)
nglis-usrm-api_1 | at
org.modelmapper.internal.MappingEngineImpl.typeMap(MappingEngineImpl.java:152)
nglis-usrm-api_1 | at
org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:106)
nglis-usrm-api_1 | at
org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:72)
nglis-usrm-api_1 | at org.modelmapper.ModelMapper.mapInternal(ModelMapper.java:573)
nglis-usrm-api_1 | at org.modelmapper.ModelMapper.map(ModelMapper.java:406)
nglis-usrm-api_1 | at
com.sip.nglis.partneruser.manager.impl.UserManagerImpl.persist(UserManagerImpl.java:61)
nglis-usrm-api_1 | at
com.sip.nglis.partneruser.manager.impl.UserManagerImpl$$FastClassBySpringCGLIB$$c52d9382
.invoke(
<generated>)
nglis-usrm-api_1 | at
org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
nglis-usrm-api_1 | at
Json:
{
"data":{
"partnerId":1,
"user":{
"userId":0,
"displayCode":"BC410",
"firstName":"Ikram",
"lastName":"Sardar Khan",
"username":"dsfsdf342423",
"password":"dsfsdfg",
"email":"[email protected]",
"phone":"03456789010",
"title":2,
"npi":"ghgrere4234qweas",
"postNominal":[
1,
2
],
"userType":1,
"active":true,
"agreementActive":true,
"accessCode":"AJ01", **This is the place where I'm getting the number format exception. **
"createdBy":1,
"createdTimestamp":1600780421007,
"roles":[
{
"createdBy":1,
"createdTimestamp":1600640026453,
"roleUId":2,
"roleUType":1,
"name":"Partner Admin",
"status":true,
"isSystemOnly":0,
"isClientRole":0,
"isPhysician":false
},
{
"createdBy":1,
"createdTimestamp":1600640026453,
"roleUId":3,
"roleUType":1,
"name":"CRM",
"status":true,
"isSystemOnly":0,
"isClientRole":0,
"isPhysician":true
}
],
"isDoctor":false
},
"createdBy":1
} }
I'm getting the number format exception on AccessCode in UserDto and Entity. You will see that on both sides it is String.
OK, this is very weird. Somehow model mapper was changing its strategy from Strict to Loose. though in post construct it was Strict when it reached the place where it was mapping the objects, the strategy was Loose.
So what I did was to remove the post construct annotation and call the method where conversions are happening. So during conversion, the strategy became strict and the above issue was resolved.