-2

I have implemented my basic requirements, which work well in one simple scenario as mentioned below code snippet. But for new requirements what is the best way out there I need help.

New requirement: Statuses in numeric format are used on other services but in request-response status representation are these user-friendly string ["Not Started", "In Progress", "Completed"]

@AllArgsConstructor
@Getter
public enum StatusEnum {
    NOT_STARTED(1,"Not Started"),
    IN_PROGRESS(2, "In Progress"),
    COMPLETED(3, "Completed");    
    private final int key;
    private final String value;
}    

Below is my MapStruct logic to convert enum to string and visa-versa conversion logic. This works fine for basic requirements. But what is the logic of the new requirement?

ActionItem.java:

private Constants.StatusEnum status;

Basic Requirements works with below implementation:

@AllArgsConstructor
@Getter
public enum StatusEnum {
    NOT_STARTED("Not Started"),  
    IN_PROGRESS("In Progress"),
    COMPLETED("Completed");
    private final String value;
}


@Mapper
public interface ActionItemMapper extents BaseMapper {
     @Mapping(source = "status", target = "status", qualifiedByName = "statusEnumToString")
     ActionItemResponse toActionItemResponse(ActionItem actionItem);
}

@Mapper
public interface BaseMapper {   
     @Named("statusEnumToString")
     default String statusEnumToString(Constants.StatusEnum statusEnum) {
        return statusEnum.getValue();
     }

     @Named("statusStringToEnum")
     default Constants.StatusEnum statusStringToEnum(String status) {
        return List.of(Constants.StatusEnum.values()).stream().filter(s -> s.getValue().equals(status)).findAny()
        .orElse(null);
     }
}
ravibeli
  • 484
  • 9
  • 30
  • Let me ask, why do you need to store numerical values in the DB? – user3159253 Jun 28 '21 at 04:15
  • 1
    From my experience storing string enum values in an indexed field of the database isn't any worse that storing integer values. After all one has a pretty limited number of quasi-constant values in an enum, usually it doesn't have not a big performance impact, but it's way easy to build queries using text constants. Some RDBMSes like postgresql have a dedicated enum types for data. – user3159253 Jun 29 '21 at 03:43
  • My basic question you are getting diverted to DB specific, forget about the database, just to explain some context I used DB, the actual intent of the question is about how to deal with the logic of Enum lookup by value, rather than enum name. Not interested in performance-related question here, as I know enum constants or integer for DB nothing great deal for performance as part of indexing them, as they are very few data across the application. Let's avoid off-topic than the intent of my question. I updated my question if it has confused you. – ravibeli Jun 29 '21 at 06:37

1 Answers1

0

I got the solution.

@AllArgsConstructor
@Getter
public enum StatusEnum {
    NOT_STARTED(1, "Not Started"),  
    IN_PROGRESS(2, "In Progress"),
    COMPLETED(3, "Completed");
    private final String key;        
    private final String value;
}


@Mapper
public interface ActionItemMapper extents BaseMapper {
     @Mapping(source = "status", target = "status", qualifiedByName = "statusEnumToString")
     ActionItemResponse toActionItemResponse(ActionItem actionItem);
}

@Mapper
public interface BaseMapper {   

   @Named("statusEnumKeyToValue")
   default String statusEnumKeyToValue(Integer status) {
       String value = null;
       for (Constants.StatusEnum statusEnum: Constants.StatusEnum.values()) {
           if (statusEnum.getKey().equals(status)) {
               value = statusEnum.getValue();
               break;
           }
       }
       if (value == null) {
           throw new IllegalArgumentException("No status value found for status key " +status);
       }
       return value;
   }

   @Named("statusEnumValueToKey")
   default Integer statusEnumValueToKey(String status) {
       return statusStringToEnum(status).getKey();
   }


   default Constants.StatusEnum statusStringToEnum(String status) {
      return List.of(Constants.StatusEnum.values()).stream().filter(s -> s.getValue().equals(status)).findAny()
        .orElseThrow()
   }
}
ravibeli
  • 484
  • 9
  • 30