I have the below Models.
Organization Model
@Data
@Entity
@Table()
@JsonIdentityInfo( generator = ObjectIdGenerators.PropertyGenerator.class, property = "id" )
public class Organization implements Serializable {
@Id
@GeneratedValue( strategy = GenerationType.IDENTITY )
private Long id;
private String name;
.
.
.
@OneToMany( mappedBy = "organization", cascade = CascadeType.MERGE, targetEntity = User.class )
private Set< User > users;
}
User Model
@Data
@Entity
@DynamicUpdate
@Table( name = RelationsConstant.TBL_USER_AUTH )
public class User implements Serializable {
@Id
@GeneratedValue( strategy = GenerationType.IDENTITY )
private Long id;
private String name;
.
.
.
@ManyToOne( cascade = CascadeType.MERGE, targetEntity = Organization.class )
@JoinColumn( nullable = false, foreignKey = @ForeignKey( name = org_usr_fk ) )
private Organization organization;
@ManyToMany( fetch = FetchType.EAGER, cascade = CascadeType.MERGE )
@JoinTable( name = RelationsConstant.TBL_USER_AUTH_ROLE, //
joinColumns = @JoinColumn( name = "base_user_id", referencedColumnName = "base_user_id", nullable = false ), //
inverseJoinColumns = @JoinColumn( name = "role_id", referencedColumnName = "id", nullable = false ), //
uniqueConstraints = { @UniqueConstraint( columnNames = { "base_user_id", "role_id" } ) } )
private Set< Role > roles;
}
Organization DTO
@Data
public class OrganizationDto implements Serializable {
private Long id;
private String name;
private Set<UserDto> users;
}
User DTO
@Data
public class UserDto implements Serializable {
private Long id;
private String name;
private OrganizationDto organization;
private Set<RoleDto> roles;
}
When I try to map these models to DTOs, I get the below error.
An error occured while processing the request org.modelmapper.MappingException: ModelMapper mapping errors:\r\n\r\n1) Error mapping Organization to OrganizationDto.
Below is the converter I used.
public class SetUserToSetUserDtoConverter implements Converter< Set< User >, Set< UserDto > > {
@Override
public Set< UserDto > convert( MappingContext< Set< User >, Set< UserDto > > context ) {
ModelMapper mapper = new ModelMapper( );
TypeMap< User, UserDto > propertyMapper = mapper.createTypeMap( User.class, UserDto.class );
propertyMapper.addMappings( mpr -> {
mpr.skip( User::getOrganization, UserDto::setOrganization );
mpr.skip( User::getRoles, UserDto::setRoles );
mpr.skip( User::getPrivileges, UserDto::setPrivileges );
mpr.skip( User::getPassword, UserDto::setPassword );
} );
Set< User > source = context.getSource( );
return source.stream( ).map( m -> mapper.map( m, UserDto.class ) ).collect( Collectors.toSet( ) );
}
}
This is how the mapper is configured.
public List< OrganizationDto > getAll() {
ModelMapper mapper = new ModelMapper( );
mapper.getConfiguration( ).setMatchingStrategy( MatchingStrategies.STRICT ).setFieldMatchingEnabled( true ).setFieldAccessLevel( Configuration.AccessLevel.PRIVATE );
/** With Converter **/
TypeMap< Organization, OrganizationDto > typeMap = mapper.createTypeMap( Organization.class, OrganizationDto.class );
typeMap.addMappings( mpr -> mpr.using( new SetUserToSetUserDtoConverter( ) ).map( Organization::getUsers, OrganizationDto::setUsers ) );
return orgRepo.findAll( ).stream( ).map( m -> mapper.map( m, OrganizationDto.class ) ).collect( Collectors.toList( ) );
}
I found that when I remove organization field from UserDto class and remove the line mpr.skip( UserDto::setOrganization ); from Converter class, this model mapping works fine.
Converter is defined to convert the User Objects Set to UserDto Objects Set and skip the conversion of OrganizationDto field.
User Objects and UserDto objects have Set<RoleDto> roles field.
The Converter skips that field without issue.
Any clue for rectifying this is highly appreciated. Thanks in advance.