Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert Java enum constant to its human-readable description string?

Tags:

java

enums

I have Java enums with a description field that I want to persist to the database instead of the enum constant name.

For example:

public enum CommitteeType {
    AUDIT_COMMITTEE("audit committee"),
    EXECUTIVE_COMMITTEE("executive committee");
    
    private final String description;
    
    CommitteeType(String description) {
        this.description = description;
    }
    
    public String getDescription() {
        return description;
    }
    
    public static CommitteeType fromDescription(String desc) {
        for (CommitteeType type : values()) {
            if (type.description.equals(desc)) {
                return type;
            }
        }
        throw new IllegalArgumentException("Invalid description: " + desc);
    }
}

I've implemented an AttributeConverter:

@Converter
public class CommitteeTypeConverter implements AttributeConverter<CommitteeType, String> {
    
    @Override
    public String convertToDatabaseColumn(CommitteeType committeeType) {
        if (committeeType == null) {
            return null;
        }
        return committeeType.getDescription();
    }
    
    @Override
    public CommitteeType convertToEntityAttribute(String s) {
        if (s == null) {
            return null;
        }
        return CommitteeType.fromDescription(s);
    }
}

And my entity:

@Entity
public class MyEntity {
    @Id
    private Long id;
    
    @Convert(converter = CommitteeTypeConverter.class)
    private CommitteeType committeeType;
}

The Problem:

When I map from DTO to Entity, the enum is correctly assigned, but JPA saves the enum constant name (AUDIT_COMMITTEE) to the database instead of the description ("audit committee").

The converter doesn't seem to be triggered. What am I missing?

like image 642
Lorenzo Tirotta Avatar asked Sep 15 '26 07:09

Lorenzo Tirotta


1 Answers

Are you declaring some annotations on fields and others on getters?

It's possible that Hibernate is using PROPERTY access instead of FIELD access and is ignoring any annotations declared on fields. In this case Hibernate falls back to its default enum handling

Option 1: Force FIELD access explicitly (note any annotations on getters will be ignored)

@Entity
@Access(AccessType.FIELD)
public class MyEntity {
    @Id
    private Long id;

    @Convert(converter = CommitteeTypeConverter.class)
    private CommitteeType committeeType;
}

Option 2: Declare all annotations on getters (use PROPERTY access)

@Entity
public class MyEntity {
    private Long id;
    private CommitteeType committeeType;

    @Id
    public Long getId() {
        return id;
    }

    @Convert(converter = CommitteeTypeConverter.class)
    public CommitteeType getCommitteeType() {
        return committeeType;
    }
}

If you want to mix the two access strategies in a single entity you can configure AccessType.FIELD on individual fields

@Entity
public class MyEntity {
    private Long id;

    @Access(AccessType.FIELD)
    @Convert(converter = CommitteeTypeConverter.class)
    private CommitteeType committeeType;

    @Id
    public Long getId() {
        return id;
    }
}

Note also that you could use ternary operators to reduce 4 lines into 1

@Converter
public class CommitteeTypeConverter implements AttributeConverter<CommitteeType, String> {
    
    @Override
    public String convertToDatabaseColumn(CommitteeType committeeType) {
        return committeeType == null ? null : committeeType.getDescription();
    }
    
    @Override
    public CommitteeType convertToEntityAttribute(String s) {
        return s == null ? null : CommitteeType.fromDescription(s);
    }
}
like image 156
lance-java Avatar answered Sep 16 '26 21:09

lance-java



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!