Is "Dynamic enumerations" an oxymoron, like "static variables"? ;-)
I've only been soaking in Spring for a short time, and I suspect I'm not thinking Spring-like yet. I would like to have a type-safe, dynamic enumeration. I've used this pattern for things like events or error codes where you want to allow subsequent sub-classes to expand the enumeration. Since "enum" can't be extended you're left with an enumeration pattern class. For example (stripped down):
public class EventType {
private String name;
private static HashMap<String, EventType> cache
= new HashMap<String, EventType>();
protected EventType(String name) {
if (cache.containsKey(name)) {
throw new RuntimeException("EventType '" + name + "' already exists!");
} else {
this.name = name;
cache.put(name, this);
}
}
public static AuditEventType parse(String name) {
return cache.get(name);
}
public static final EventType EVENT_START = new AuditEventType("Start");
public static final EventType EVENT_END = new AuditEventType("End");
public static final EventType EVENT_FAIL = new AuditEventType("Fail");
}
The problems start when I add Spring to the mix. Since it's only a string, I've annotated EventType as "@Embeddable", and classes that use it annotate that member as "@Embedded". This seemed to work great until it came time for querying using queryDSL-jpa. DSL would try to convert the DB text to an EventType, which then would have a type mismatch with strings. That is, I couldn't say: WHERE EventType = "Start"
. I got around this (not elegantly) by having the class with such a field store it as a String, and parse it to an EventType object in the getter. So now it's just a plain ol' string as far as JPA is concerned.
Now I'm running into an issue with the service API. I have a method with an EventType parameter. The problem is that the JsonRpcServer class is trying to convert the String to an EventType by instantiating it. This of course throws an "already exists!" exception.
I can probably solve this second issue with @JsonTypeResolver (which I'm reading up on now). But all of these shenanigans feel wrong. This must be a common issue and there's got to be a better solution. What's the proper way of handling such classes in Spring? (where it's not a bean, really, and has a protected constructor).
(I'm leaving out some specifics about some proprietary libraries our code uses, and which might not let me adopt an answer like "Oh, you should be using 'X' instead." Thanks for understanding.)