Heya.
I realize now that part of my problem is build dependency race conditions.
I can't write Converter<JooqEnum, MyEnum> because our persistence utilities live in a module that is built before the module which generates jooq.
The reasons for this are long and ugly, but suffice to say that in order to share code with clients, and not have a totally hacked build, it has to be this way
(we can't compile our DbGenerator with references to types that are generated by the DbGenerator).
What I wound up doing is writing a converter that resorts to some ugly reflection to avoid the dependency on a type that does not exist yet:
public class VisibilityConverter<T extends EnumType> implements Converter<T, Visibility> {
private static class GeneratedTypeReflection {
private final Lazy<Class<?>> cls;
private final Lazy<Method> valueOf;
private GeneratedTypeReflection(String type) {
this.cls = Lazy.deferredUnsafe(()->getClass().getClassLoader().loadClass(type));
this.valueOf = Lazy.deferredUnsafe(()->cls.get().getMethod("valueOf", String.class));
}
}
private final GeneratedTypeReflection type;
public VisibilityConverter() {
type = new GeneratedTypeReflection("com.redcurrent.data.sql.generated.enums.RcVisibility");
}
@Override
public Visibility from(T v) {
if (v == null) {
return null;
}
return Visibility.valueOf(v.getLiteral());
}
@Override
public T to(Visibility v) {
if (v == null) {
return null;
}
try {
return (T) type.valueOf.get().invoke(null, v.name());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public Class<T> fromType() {
return Class.class.cast(type.cls.get());
}
@Override
public Class<Visibility> toType() {
return Visibility.class;
}
}
Then standard custom converter / forced type semantics on the above Visibility class.
new ForcedType()
.withName(Visibility.class.getCanonicalName())
.withExpression("visibility")
.withUserType(Visibility.class.getCanonicalName())
.withConverter(VisibilityConverter.class.getCanonicalName())
,
new CustomType()
.withName(Visibility.class.getCanonicalName())
.withConverter(VisibilityConverter.class.getCanonicalName())
It may be worthwhile to adopt this pattern into a Jooq ReflectionEnumConverter which takes the fully qualified name of the expected generated enum type;
I will likely make such an abstraction during code review, but thought I would share in case others have issues with being able to reference the jooq enum.