Search code examples
mysqlenumsmybatispojo

MyBatis retrieve Integer as Enum from MySql DB


I hava a POJO which contains an enum property.

[Speed.java]

public class SpeedEntry implements Serializable {

    [...]

    private int idSpeed;
    private SpeedStatus status; // enum Property

    [...]

[SpeedStatus.java]

public enum SpeedStatus {

[...]

VALID(1), INVALID(2), UNKNOWN(0);   // Possible values.

private int value;

// Default constructor
private SpeedStatus(final int pValue) {
    this.value = pValue;
}
[...]

And I would like to store and retrieve the Speed object and get its properties filled as usual with MyBatis. The column assigned to SpeedStatus was created as an INT(11).

In this case, doing the INSERT was quite direct accessing its internal value property with:

#{status.value}

However, retrieving the object and getting its enum value filled from the integer stored in the database has not been as easier as inserting it. I tried, without luck, using a resultMap:

[speedMapper.xml]

<resultMap id="speedMap" type="Speed">
        <result property="idSpeed" column="idSpeed" />
        <result column="status" property="status.value" 
            typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>
</resultMap>

So...it is possible to achieve what I am looking for? Is there any simple clarifying example around there?

What is the best alternative? Should I change the type stored in the database to "enum" ?

Thanks in advance.


Solution

  • In your insert statement you direct access its internal value by

    #{status.value}
    

    By this way, you insert VALID by value 1, INVALID by value 2, NUKNOWN by the value 0. But in your retrival statements, you using the resultMap defined by

    typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"
    

    That means you map the table int(11) field to Enum POJO property using the

    SpeedStatus.ordinal()
    

    Enum value will be mapped by the order defined in SpeedStatus. So in select statements table field value 0 mapped to VALID, 1 mapped to INVALID, 2 mapped to UNKNOWN.

    If you still want to use EnumOrdinalTypeHandler you should defined the Enum value equal to its ordinal() value.

    public enum SpeedStatus {
    
        UNKNOWN(0), VALID(1), INVALID(2); 
    
        private int value;
    
        private SpeedStatus(final int pValue) {
            this.value = pValue;
        }
    

    }