I'm trying to map an entity field that is a set of Java Class objects to a comma-delimited string of the simple class names in the database. The implementation essentially follows the solution proposed by this answer on Stackoverflow:
https://stackoverflow.com/a/34061723.
Field definition in my entity:
Code:
@Convert(converter = ClassSimpleNameConverter.class)
private Set<Class<?>> types;
JPA converter methods - `types` is a Map of (simple class name String, Class) pairs that are allowed:
Code:
/* @see javax.persistence.AttributeConverter#convertToDatabaseColumn(java.lang.Object) */
@Override
public String convertToDatabaseColumn(final Set<Class<? extends T>> actual)
{
if (actual == null) return null;
return actual.stream()
.map(Class::getSimpleName)
.filter(t -> types.containsKey(t))
.collect(Collectors.joining(","));
}
/* @see javax.persistence.AttributeConverter#convertToEntityAttribute(java.lang.Object) */
@Override
public Set<Class<? extends T>> convertToEntityAttribute(final String dbData)
{
if (dbData == null) return null;
return Arrays.stream(dbData.split(","))
.map(t -> types.get(t))
.collect(Collectors.toSet());
}
This works nicely except when creating the JPA meta model for the entity using Hibernate's meta model generator, version 5.2.12 (pretty recent :-). Due to the fact that the unconverted field's type is `Set`, the corresponding constant in the metamodel is typed to `SetAttribute<MyEntity, Class> types`. This, in turn, leads to the following exception when the container deploys the application:
Code:
ERROR [org.hibernate.metamodel.internal.MetadataContext] (ServerService Thread Pool -- 66) HHH015007: Illegal argument on static metamodel field injection : mypackage.MyEntity_#types; expected type : org.hibernate.metamodel.internal.SingularAttributeImpl; encountered type : javax.persistence.metamodel.SetAttribute
To me, this appears to be a kind of corner case, if not a gap in the design of the JPA specification. What would be the correct behavior here? Should the meta model generator consider the target type of an AttributeConverter (which is String in this case). I tried to annotate the field as @Basic but that didn't have an effect.