Saravana Kumar M
Saravana Kumar M

Reputation: 490

mapstruct: How to construct a string from an object's property in mapstruct?

I have the below class structure.

public class Comment
{
  private Integer id;
  private String text;

  //getters & setters
}

@Mapper(componentModel = "spring")
public interface CommentMapper
{
    String map(Comment comment);
    Comment map(String text);
    //Comment map(String someNameHere);
}

The below is the implementation generated by mapstruct

@Override
public String map(Comment comment) {
if ( comment == null ) {
    return null;
}
String string = new String();
return string;
}

@Override
public Comment map(String text) {
if ( text == null ) {
    return null;
}
Comment comment = new Comment();
comment.setText( text );
return comment;
}

/*
@Override
public Comment map(String someNameHere) {
    if ( someNameHere == null ) {
        return null;
    }
    Comment comment = new Comment();
    return comment;
}
*/

Question1: The map method which takes the Comment object as parameter and returns the string is just returning an empty string object instead of setting the text property on the string and return it. Why? and how to get the text property of the comment object returned?

Question2: when the parameter name of the map method is text it generates implementation utilizing the text property from the class or else just empty comment object. I really surprised to see that mapstruct generates different implementations depends on the parameter name too. Any explanation?

Note: The Comment object is used as a property inside another object. There i need the above mentioned behavior. For now i managing it this way. @Mapping(source = "entity.comment.text", target = "comment") @Mapping(source = "dto.comment", target = "comment.text")

Upvotes: 5

Views: 7505

Answers (1)

jannis
jannis

Reputation: 5210

There's an issue like yours in MapStruct's bugtracker (#584 Cannot create a method where the returned object is a String):

MapStruct generally operates on Java beans, i.e. it expects properties on the source and target objects. For your case I'd just make the mapper an abstract class and implement the method from hand (code generation would give you no advantage really):

String dtoToString(Dto dto) {
    return dto.getField1();
}

That method can then be used by other (generated) methods for mapping a DTO property into a string property. Instead of declaring this manually written method on an abstract mapper itself you also can declare it on another class and import it through @Mapper#uses().

-- https://github.com/mapstruct/mapstruct/issues/584#issuecomment-117523614

IMHO the way you're doing it currently is fine and i'd stick to that.

Upvotes: 5

Related Questions