-1

Background

I'm trying to convert this Ebean example from Java into Kotlin: http://ebean-orm.github.io/docs/mapping/extension/dbenumvalue

Here's the sample Java code:

public enum Status {

  NEW("N"),
  ACTIVE("A"),
  INACTIVE("I");

  String dbValue;
  Status(String dbValue) {
    this.dbValue = dbValue;
  }

  // annotate a method that returns the value
  // in the DB that the enum element maps to

  @DbEnumValue
  public String getValue() {
    return dbValue;
  }
}

Kotlin

I expected the following in Kotlin:

// ERROR: This annotation is not available to target 'value parameter'
enum class Status(@DbEnumValue(storage = DbEnumType.VARCHAR) value: String) {
    NEW("N"),
    ACTIVE("A"),
    INACTIVE("I")
}

Or maybe:

// ERROR: Expecting , or ) after "value:String"
enum class Status(val value:String
                      @DbEnumValue(storage = DbEnumType.VARCHAR)
                      get() = value) {
    NEW("N"),
    ACTIVE("A"),
    INACTIVE("I")
}

The following makes sense to me and actually compiles, but the combination of the dbValue parameter for the constructor with a separate value field with getter for the annotation feels wasteful somehow.

enum class Status (val dbValue:String) {
    NEW("N"),
    ACTIVE("A"),
    INACTIVE("I");

    val value: String
        @DbEnumValue(storage = DbEnumType.VARCHAR)
        get() = dbValue
}

When I let IntelliJ convert the Java to Kotlin, it does this:

enum class Status private constructor(dbValue: String) {
    NEW("N"),
    ACTIVE("A"),
    INACTIVE("I");

   var value: String internal set

    init {
        @DbEnumValue(storage = DbEnumType.VARCHAR)
        this.value = dbValue
    }
}

I added the annotation to what IntelliJ produced, but it took me several guesses to figure out where to put it.

Questions

  • Why private constructor?
  • Why var value without a get()?
  • What is internal set?
  • Why init?
  • Why the extra dbValue variable? (I think to pass the value from the constructor to the public annotated get method).
  • Is that even right?
  • What is the idiomatic way to do this?

Any explanation, correction, or improvement would be appreciated. If you think this belongs on codeReview, I'm OK with you moving it.

GlenPeterson
  • 4,866
  • 5
  • 41
  • 49

2 Answers2

0

I think the cleanest solution is to use @EnumValue instead of @DbEnumValue:

enum class Status {
    @EnumValue("N") NEW,
    @EnumValue("A") ACTIVE,
    @EnumValue("I") INACTIVE
}
GlenPeterson
  • 4,866
  • 5
  • 41
  • 49
0

I think the second way is the cleanlst, just a bit of syntax error

enum class Status(@get:DbEnumValue val value: String) {
    NEW("N"),
    ACTIVE("A"),
    INACTIVE("I")
}

kotlin docs link:Annotation Use-site Targets

tenko
  • 1
  • 1