Dashboard > iBATIS DataMapper > Home > Frequently Asked Questions > How do I use Enums with annotations
How do I use Enums with annotations
Added by Larry Meadors, last edited by Larry Meadors on Jun 13, 2007
Labels: 
(None)


Here's how I do this.

I have an interface that I use for my enums:

public interface ValueEnum {
    Object getValue();
    }

It looks like this to implement an enum that uses this:

public enum EmploymentTermReason implements ValueEnum {
    Voluntary("V"), Fired("F"), Retired("R");
    
    private String value;
    
    private EmploymentTermReason(String value){
    this.value = value;
    }
    
    public String getName(){
    return name();
    }
    
    public Object getValue() {
    return value;
    }
    }

The getName() method is just for the sake of reflection - blah.name will work for this enum now.

Next, I created an EnumTypeHandler annotation:

@Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface EnumTypeHandler {
    Class enumClass();
    int jdbcType();
    }

Here's the implementation of that:

public class EnumTypeHandlerImpl implements TypeHandlerCallback {
    private int jdbcType;
    
    private Map<Object, Enum> map = new HashMap<Object, Enum>();
    
    protected EnumTypeHandlerImpl() {
    if(this.getClass().isAnnotationPresent(EnumTypeHandler.class)){
    EnumTypeHandler eth = this.getClass().getAnnotation(EnumTypeHandler.class);
    jdbcType = eth.jdbcType();
    Class aClass = eth.enumClass();
    for(Object o : aClass.getEnumConstants()){
    Enum e = (Enum) o;
    ValueEnum v = (ValueEnum) o;
    Object value = v.getValue();
    map.put(value, e);
    if(value instanceof String){
    // special case, we want to use toString and value when reading...
    					map.put(v.toString(), e);
    }
    }
    }else{
    throw new RuntimeException("Must provide @EnumTypeHandler annotation.");
    }
    }
    
    public void setParameter(ParameterSetter parameterSetter, Object object)
    throws SQLException {
    if (object == null) {
    parameterSetter.setNull(jdbcType);
    } else {
    ValueEnum anEnum = (ValueEnum) object;
    parameterSetter.setObject(anEnum.getValue(), jdbcType);
    }
    }
    
    public Object valueOf(String string) {
    return string;
    }
    
    public Object getResult(ResultGetter resultGetter) throws SQLException {
    Object value = resultGetter.getObject();
    
    if (resultGetter.wasNull()) {
    return null;
    }
    
    return map.get(value);
    }
    
    }

And a complete type handler:

@EnumTypeHandler(enumClass = EmploymentTermReason.class, jdbcType = Types.VARCHAR)
    public class EmploymentTermReasonTypeHandler extends EnumTypeHandlerImpl {
    
    }

Further enums simply implement the ValueEnum interface, then creating a type handler is simply a matter of extending the EnumTypeHandlerImpl class, providing the enumClass and jdbcType values, and registering the type handler in your iBATIS configuration.


Site running on a free Atlassian Confluence Open Source Project License granted to OSS. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.5 Build:#811 Jul 25, 2007) - Bug/feature request - Contact Administrators