简体   繁体   中英

Generate ID for mapped item

On our project, it's customary to use mapstruct for all mappings. In this unique case, I'm not creating an Entity, but rather a DTO. However this DTO requires I generate a UUID, and I'd rather not use the expression option.

@Mapping(target = "trackId", expression = "java(UUID.randomUUID().toString())")
FileUploadRequest inventoryToFileUpload(Inventory inventory);

I'd much rather have the compiler as a friend at all times in life. Also what do you do if the generation strategy isn't a 30 character width one-liner?

My preferred method is as follows:

@Mapping(target = "trackId", qualifiedByName = "generateUUID"),
FileUploadRequest inventoryToFileUpload(Inventory inventory);


@Named("generateUUID")
default String generateUuid() {
    return UUID.randomUUID().toString();
}

Sadly the above does not work. I have to give it a source, which is nonsense. Or maybe there's a way of specifying I don't rely on any parameter?

Here is code that does work:

// Ommiting other mappings for clarity
@Mapping(target = "trackId", source = "id", qualifiedByName = "generateUUID")
FileUploadRequest inventoryToFileUpload(Inventory inventory);

@Named("generateUUID")
default String generateUuid(final String nonsense) {
    return UUID.randomUUID().toString();
}

This generates the following line of code

fileUploadRequest.setTrackId(this.generateUuid(inventory.getId()));

But... the parameter is superflous, as can easily be seen. I know that this does not ACTUALLY matter. But it seems either like an oversight, or me not understanding how to declare that I do not have a source for this, I just want the mapper to call my method.

Again, expression is not a valid answer, please do not propose it. UNLESS you can do expression = "java(generateUuid())" ?

MapStruct is about mapping between different objects. That's why you can't use an empty method (without expression ).

What I would suggest is to indeed use Mapping#expression . However, to simplify it for you, you can use something like:

public class MappingUtils {

    public static String GENERATE_UUID_EXPRESSION = "java(" + MappingUtils.class.getCanonicalName() + ".generateUuid())"


    public static String generateUuid() {
        return UUID.randomUUID().toString();
    }

}

And then in your mappers you can do:

@Mapper
public interface MyMapper {

    @Mapping(target = "trackId", expression = MappingUtils. GENERATE_UUID_EXPRESSION)
    FileUploadRequest inventoryToFileUpload(Inventory inventory);

}

Doing this you have the expression in a single place and you have aa method that performs the generation.

The generated code will use the full qualified name of the MappingUtils . In case you want to avoid that you will need to add MappingUtils to Mapper#imports and then use MappingUtils.class.getName() instead in your expression.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM