1

I have an enum defined as below where the values are supposed to be as -2, -1, 0, 1, 2:

public enum Rating {

    EXTREMELY_DISSATISIFIED(-2),
    DISSATISFIED(-1),
    NEUTRAL(0),
    SATISFIED(1),
    EXTREMELY_DISSATIFIED(2);

    private final int rating;

    Rating(int rating) {
        this.rating = rating;
    }

    public int getValue() {
        return rating;
    }
}

In my model, I have an attribute called rating as shown below:

@Entity
public class Feedback {
    @Column(nullable=false)
    private Rating rating;

    public Feedback() {}

    public Rating getRating() {
        return rating;
    }
    public void setRating(Rating rating) {
        this.rating = rating;
    }
}

Then, through a RESTful API, I saved rating using the following code:

@Service
public class FeedbackService {

    @Autowired
    private FeedbackRepository feedbackRepository;

    public Feedback addFeedback(Feedback feedback) {
        return feedbackRepository.save(feedback);
    }
}

So, when I POST a request like:

{
   "rating": "EXTREMELY_DISSATISFIED"
}

I expect to see the value -2 in the POSTgres database. However, I still see 0 as a normal enum would start with 0. How can I adjust this for database to store the values as -2, -1, 0, 1 and 2?

kovac
  • 4,945
  • 9
  • 47
  • 90
  • A JPA provider will not save any custom enum values unless that provider has some special handling for it, and most don't. I know that DataNucleus supports one way, as per http://www.datanucleus.org:15080/products/accessplatform_5_1/jpa/mapping.html#_enums , but depends which provider are using. –  Nov 09 '17 at 09:43
  • Possible duplicate of [Map enum in JPA with fixed values?](https://stackoverflow.com/questions/2751733/map-enum-in-jpa-with-fixed-values) – David SN Nov 09 '17 at 09:59

2 Answers2

4

You can use a custom converter with @Convert annotation and AttributeConverter like this:

@Convert(converter = EnumToIntValue.class)
private Rating rating;

And write your EnumToIntValue converter class, this way:

public class EnumToIntValue implements AttributeConverter<Rating, Integer> {

    @Override
    public Integer convertToDatabaseColumn(final Rating rating) {
        return rating.getValue();
    }

    @Override
    public Rating convertToEntityAttribute(final int dbData) {
        if (dbData == -2) {
            return Rating.EXTREMELY_DISSATISIFIED;
        } else if (dbData == -1) {
            return Rating.DISSATISFIED;
        } else if (dbData == 0) {
            return Rating.NEUTRAL;
        } else if (dbData == 1) {
            return Rating.SATISFIED;
        }else if(dbData == 2){
            return Rating.EXTREMELY_SATIFIED;
        }else{
            return null
        }
    }
}
cнŝdk
  • 31,391
  • 7
  • 56
  • 78
  • I decided to go with string values instead of int as this does not make a big difference in my case as compared to the complexity to make it work. – kovac Nov 11 '17 at 07:15
2

You can always use an AttributeConverter which can customize the stored value. HERE is a nice tutorial.

Flown
  • 11,480
  • 3
  • 45
  • 62