Vanitha V
Vanitha V

Reputation: 153

Storing Enum custom Values with JPA

I have an enum:

public enum NotificationType {

    OPEN("open"),
    CLOSED("closed");

    public String value;

    NotificationType(String value) {
        this.value = value;
    }
}

I want to pass the custom string open or closed rather than OPEN or CLOSED to entity. Currently, I've mapped it in the entity as follows:

@Enumerated(EnumType.STRING)
private NotificationType notificationType;

Which is the best way to store/ fetch enum value?

Upvotes: 8

Views: 3337

Answers (2)

user731136
user731136

Reputation:

Yes, basically you have to develop a custom converter for that but I suggest you use Optional to avoid dealing with null and exceptions.

Add in NotificationType:

public static Optional<NotificationType> getFromValue(String value) {
   return Optional.ofNullable(value)
                  .flatMap(dv -> Arrays.stream(NotificationType.values())
                                    .filter(ev -> dv.equals(ev.value))
                                    .findFirst());
}

Create the required converter:

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

@Converter(autoApply = true)
public class NotificationTypeConverter implements AttributeConverter<NotificationType, String> {

   @Override
   public String convertToDatabaseColumn(NotificationType notificationType) {
      return null == notificationType ? null : notificationType.value;
   }

   @Override
   public NotificationType convertToEntityAttribute(String databaseValue) {
      return NotificationType.getFromValue(databaseValue)
                             .orElse(null);
   }
 }

And now, you only have to modify your model:

@Entity
@Table
public class MyEntity {

   @Convert(converter=NotificationTypeConverter.class)
   private NotificationType notificationType;
}  

Upvotes: 2

Kartik
Kartik

Reputation: 7917

You can create a custom converter like this:

@Converter(autoApply = true)
public class NotificationTypeConverter implements AttributeConverter<NotificationType, String> {

    @Override
    public String convertToDatabaseColumn(NotificationType notificationType) {
        return notificationType == null
                ? null
                : notificationType.value;
    }

    @Override
    public NotificationType convertToEntityAttribute(String code) {
        if (code == null || code.isEmpty()) {
            return null;
        }

        return Arrays.stream(NotificationType.values())
                .filter(c -> c.value.equals(code))
                .findAny()
                .orElseThrow(IllegalArgumentException::new);
    }
}

And perhaps you'll need to remove annotation from your notificationType field so that this converter takes effect.

Upvotes: 8

Related Questions