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