18

My model class (piece):

public class User ... {

    @Enumerated(STRING)
    private Status status;

    ...

    public enum Status {

        ACTIVE,
        INACTIVE;

        @Override
        public String toString() {
            return this.name().toLowerCase();
        }
    }

    ...

    public String getStatus() {
        return status.name().toLowerCase();
    }

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

As you see above I override toString method, but no effect. Enumeration store in database as ACTIVE or INACTIVE.

P.S. I use hibernate jpa

Thanks for help!

P.S.S. I ask because I write REST service that produces json (in json object better use lower case, if I'm not mistake)

Jonik
  • 80,077
  • 70
  • 264
  • 372
eugenes
  • 701
  • 2
  • 7
  • 16
  • Your code works for me. `toString` and `getStatus` both returns lowercase strings. Are you sure you are not calling `name()` when constructing the json? – Tobber Oct 23 '13 at 18:10
  • @Bittenus, I try to store enum in the database as lowercase string. – eugenes Oct 24 '13 at 08:30
  • 1. Are you using a library to parse the enum or are you parsing it your self? 2. Is the code, that parses the enum for the database, using `name()` or `toString`? – Tobber Oct 24 '13 at 09:47
  • I use next libraries: spring-orm, hibernate-core and hibernate-entitymanager – eugenes Oct 24 '13 at 10:47
  • the accepted answer is the only way. It's a pity, Spring should use enum getters and setters by default if no converter defined – kiedysktos May 23 '17 at 08:17

4 Answers4

14

write a converter class, annotated with @Converter , which implements javax.persistence.AttributeConverter<YourEnum, String>. There are two methods:

public String convertToDatabaseColumn(YourEnum attribute){..}
public YourEnum convertToEntityAttribute(String dbData) {..}

there you can apply your upper/lower case logic.

Later you can annotated your field, for using the given converter.

Kent
  • 189,393
  • 32
  • 233
  • 301
  • 1
    Thank you, Kent. That helped me. Just to complete, because I had to search for it: Annotating the field to use the converter works like this: `@Colum` `@Convert(converter=YourEnumConverter.class)` – Buka Sep 11 '15 at 12:47
  • 1
    @Buka right! Also, note that you should remove `@Enumerated` if you use `@Convert`, otherwise converter is ignored – kiedysktos May 23 '17 at 10:37
7

Here's a quick and practical example of using AttributeConverter (introduced in JPA 2.1)

Update your enum class:

public enum Status {
    ACTIVE,
    INACTIVE;

    public String toDbValue() {
        return this.name().toLowerCase();
    }

    public static Status from(String status) {
        // Note: error if null, error if not "ACTIVE" nor "INACTIVE"
        return Status.valueOf(status.toUpperCase());
    }
}

Create attribute converter:

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

@Converter(autoApply = true)
public class StatusConverter implements AttributeConverter<Status, String> {
    @Override
    public String convertToDatabaseColumn(Status status) {
        return status.toDbValue();
    }

    @Override
    public Status convertToEntityAttribute(String dbData) {
        return Status.from(dbData);
    }
}

If autoApply is set to true, you don't need to add the javax.persistence.Convert annotation to all attributes that shall be converted. Otherwise, apply the converter:

import javax.persistence.Convert;
import javax.persistence.Entity;

@Entity
public class User {

    @Convert(converter = StatusConverter.class)
    @Enumerated(STRING)
    private Status status;

    // ... other fields, constructor(s), standard accessors
}
naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
2

If you're using Jackson for the REST service let Jackson do the conversion at the REST boundary. Your question doesn't state a requirement for the DB to store lower case or for the application to process lower case.

public enum Status {
    STARTED,
    CONSUMING,
    GENERATING,
    FAILED,
    COMPLETED,
    DELETED;

    /**
     * Serialises to and from lower case for jackson.
     *
     * @return lower case Status name.
     */
    @JsonValue
    public String toLower() {
        return this.toString().toLowerCase(Locale.ENGLISH);
    }
}
-1

Best practice is to use the upper-case for enum constants.

I see two options

  1. Use lower-case in enum (not a good practice)
  2. Change the getter method (getStatus method) of the bean using this enum to return lower case. (best possible option)
Abhijith Nagarajan
  • 3,865
  • 18
  • 23
  • In the getter method I return Status enumeration. I change return type to String and change implementation to return status.name().toLowerCase(), but still no effect. Sorry – eugenes Oct 23 '13 at 16:49