15

I want to convert String to enum using mapstruct

enum TestEnum {
   NO("no");
   String code;

   TestEnum(String code) {
     this.code = code
   }

   public String getCode() {
    return code;
   }
}

I have a code that I've got from service and I want to convert this code to Enum how to do it with easier way by mapstruct

DPM
  • 1,960
  • 3
  • 26
  • 49
m.zemlyanoi
  • 335
  • 1
  • 5
  • 15
  • 1
    Possible duplicate of [How can I map an enum to a boolean with mapstruct?](https://stackoverflow.com/questions/43356232/how-can-i-map-an-enum-to-a-boolean-with-mapstruct) – Filip Feb 01 '18 at 22:26

3 Answers3

10

The following code worked for me.

@Mappings({
        @Mapping(source = "genderDTO.name", target = "genderName")
})
GenderRecord dtoTogenderRecord(GenderDTO genderDTO);
  • "genderName" is the Enum
  • "genderDTO.name" is the String

The result was:

@Override
public GenderRecord dtoTogenderRecord(GenderDTO genderDTO) {
    if ( genderDTO == null ) {
        return null;
    }

    GenderRecord genderRecord = new GenderRecord();

    if ( genderDTO.getName() != null ) {
        genderRecord.setGenderName( Enum.valueOf( GenderType.class, genderDTO.getName() ) );
    }

    return genderRecord;
}

I also use the following at the interface level to ensure null checks:

@Mapper(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
jpCharger
  • 109
  • 2
  • But, I think it wont work if your genderDTO .getName() is not a enum constant. It will throw Illegalargumentexception. `no enum constant for object error` – Brooklyn99 Mar 04 '21 at 22:27
  • @Brooklyn99 : Yes you are right it will throw exception but i feel it is an expected behaviour If we compare enum with string then the string should match with valueOf(Enum) – Jeya Kumar Sep 03 '21 at 15:08
5

Here is a solution with an abstract mapper, but if you want you can convert it with a default methode or a class

@Mapper
public abstract class TestMapper {

    abstract Source toSource(Target target);
    abstract Target totarget(Source source);

    String toString(TestEnum test){
        return test.getCode();
    }
    TestEnum toEnum(String code){
        for (TestEnum testEnum : TestEnum.values()) {
            if(testEnum.equals(code)){
                return testEnum;
            }
        }
        return null;
    }
}

public class Source {    
    String value;    
    public String getValue() {
        return value;
    }    
    public void setValue(String value) {
        this.value = value;
    }    
}

public class Target {
    TestEnum value;
    public TestEnum getValue() {
        return value;
    }
    public void setValue(TestEnum value) {
        this.value = value;
    }
}
Bertrand Cedric
  • 653
  • 6
  • 11
  • May I know what is the default Model and Class your referring. For my project in many places, we need to convert From String to Enum and vice-versa using map-struct. – Sharan De Silva Mar 27 '19 at 12:41
  • 2
    I guess you meant `if(testEnum.name().equals(code)){` – lrkwz Jun 25 '20 at 14:29
2

MapStruct only calls the "setProperty(PropertyType)" function, so simply use polymorphism in your setters

For DTO:

    public void setStatus(String status) {
        this.status = status;
    }

    public void setStatus(ProjectStatus status) {
        this.status = status.toString();
    }

For Entity:

    public void setStatus(ProjectStatus status) {
        this.status = status;
    }

    public void setStatus(String status) {

        switch (status) {
        case "PENDING_WITH_RM":
            this.status = ProjectStatus.PENDING;
            break;
        case "PENDING_WITH_OPS":
            this.status = ProjectStatus.PENDING;
            break;
        case "COMPLETED":
            this.status = ProjectStatus.COMPLETED;
            break;
        default:
            this.status = ProjectStatus.DRAFT;
        }
    }
Ryan Augustine
  • 1,455
  • 17
  • 14