Inspired by this answer, I have wrote a custom conveter (you can find the whole working example in the Github repo). for Dozer to convert between:
public class MyEntity {
private List<ObjectId> attachmentIds;
public List<ObjectId> getAttachmentIds() { return attachmentIds; }
public void setAttachmentIds(List<ObjectId> attachmentIds) {
this.attachmentIds = attachmentIds;
}
}
And its DTO:
public class MyEntityDto {
private List<FileDataDto> attachments;
public List<FileDataDto> getAttachments() { return attachments; }
public void setAttachments(List<FileDataDto> attachments) {
this.attachments = attachments;
}
}
MyEntity
holds only the ids for files stored in Mongo databse. Its DTO which is sent to frontend in JSON, is supposed to contain both id and a filename of a file (which is the content of the FileDataDto
class). My Converter:
public class FileIdToFileDataConverter extends DozerConverter<ObjectId, FileDataDto> {
public FileIdToFileDataConverter() {super(ObjectId.class, FileDataDto.class); }
@Override
public FileDataDto convertTo(ObjectId source, FileDataDto destination) {
if (source == null) {
return null;
}
FileDataDto fileData = destination == null ? new FileDataDto() : destination;
fileData.setId(source.toString());
// fetch the file from repository and update the name from db
fileData.setFilename("myfile.txt");
return fileData;
}
@Override
public ObjectId convertFrom(FileDataDto source, ObjectId destination) {
return source == null ? null : new ObjectId(source.getId());
}
}
The conversion works as expected in the MyEntity
-> MyEntityDto
direction. However, it fails in the opposite. It uses the ObjectId
created by Dozer (passed as the destination
argument) instead of the one that is returned by the converter. This test
@Test
public void dtoToMyEntity() {
MyEntityDto dto = new MyEntityDto();
FileDataDto fileData = new FileDataDto();
fileData.setFilename("file.txt");
fileData.setId(new ObjectId().toString());
dto.setAttachments(Arrays.asList(fileData));
MyEntity myEntity = mapper.map(dto, MyEntity.class);
assertEquals(fileData.getId(), myEntity.getAttachmentIds().get(0).toString());
}
Fails with an example message:
org.junit.ComparisonFailure:
Expected :56b0a9d110a937fc32a6db18
Actual :56b0a9d110a937fc32a6db19
You can find the whole test and configuration I use in the Github repo.
How to make the converter work in both ways?