Как сопоставить список перечислений с Varchar с помощью Hibernate 6.2 ⇐ JAVA
Как сопоставить список перечислений с Varchar с помощью Hibernate 6.2
I'm currently trying to make a custom Hibernate Type to map a List of Enum into a Varchar of comma-separated elements. For that, I've written my own JavaType (old JavaTypeDescriptor) and my own BasicType. The problem is, for my second class, that I need an instance of my JavaType.
Attempt 1
In Hibernate 5, it was possible to set the JavaType when needed, using the Parameter annotation and by setting in it the type (with AbstractStandardBasicType#setJavaTypeDescriptor). In the version 6.2 of Hibernate, the method is not available anymore and the field javaTypeDescriptor (now javaType) is final, so I'm not able to do it. Here is the code I've tried :
public class EnumListJavaType extends AbstractJavaType { private final Class enumClass; private static final String SEPARATOR = ","; public EnumListJavaType(Class enumClass) { super(List.class); this.enumClass = enumClass; } @Override public X unwrap(List value, Class type, WrapperOptions options) { if (value == null) return null; return (X) toString(value); } @Override public List wrap(X value, WrapperOptions options) { if (value == null) return null; return fromString(value.toString()); } @Override public String toString(List value) { return (String) value.stream() .map(Enum::name) .collect(Collectors.joining(SEPARATOR)); } public List fromString(String string) { if (StringUtils.isEmpty(string)) return null; return Arrays.stream(string.split(SEPARATOR)) .map(s -> Enum.valueOf(enumClass, s)) .collect(Collectors.toList()); } } public class EnumListType extends AbstractSingleColumnStandardBasicType implements DynamicParameterizedType { /** * Here the JavaType is not passed as we don't know yet the enum class. */ public EnumListType() { super(VarcharJdbcType.INSTANCE, null); @Override public String getName() { return "enum_list"; } @Override public String[] getRegistrationKeys() { return new String[] { getName(), "EnumList", EnumSet.class.getName() }; } @Override public void setParameterValues(Properties parameters) { // Here I'm not able to set the JavaType anymore as there is no such method /* String enumClassName = (String) parameters.get("enumClass"); try { setJavaType(new EnumSetJavaType(Class.forName(enumClassName))); } catch (ClassNotFoundException e) {}*/ } The only way I see now is by removing the generic and to define my JavaType as a List. But I hope there is a more clean way of doing this.
Attempt 2
I've then thought about creating a Factory to create the HavaType when needed, by using the annotation @TypeDef. Something like :
public class EnumListTypeFactory implements TypeDef { @Override public Class getTypeClass() { return EnumListType.class; } @Override public String getTypeMethod() { return "forEnumClass"; } public static EnumListType forEnumClass(String enumClassName) { try { Class enumClass = (Class) Class.forName(enumClassName); return new EnumListType(new EnumListJavaType(enumClass)); } catch (ClassNotFoundException e) { throw new HibernateException("Enum class not found", e); } } But in Hibernate 6, the annotation @TypeDef seems to have been removed.
I will be grateful if you have any suggestion about it !
Источник: https://stackoverflow.com/questions/768 ... ernate-6-2
I'm currently trying to make a custom Hibernate Type to map a List of Enum into a Varchar of comma-separated elements. For that, I've written my own JavaType (old JavaTypeDescriptor) and my own BasicType. The problem is, for my second class, that I need an instance of my JavaType.
Attempt 1
In Hibernate 5, it was possible to set the JavaType when needed, using the Parameter annotation and by setting in it the type (with AbstractStandardBasicType#setJavaTypeDescriptor). In the version 6.2 of Hibernate, the method is not available anymore and the field javaTypeDescriptor (now javaType) is final, so I'm not able to do it. Here is the code I've tried :
public class EnumListJavaType extends AbstractJavaType { private final Class enumClass; private static final String SEPARATOR = ","; public EnumListJavaType(Class enumClass) { super(List.class); this.enumClass = enumClass; } @Override public X unwrap(List value, Class type, WrapperOptions options) { if (value == null) return null; return (X) toString(value); } @Override public List wrap(X value, WrapperOptions options) { if (value == null) return null; return fromString(value.toString()); } @Override public String toString(List value) { return (String) value.stream() .map(Enum::name) .collect(Collectors.joining(SEPARATOR)); } public List fromString(String string) { if (StringUtils.isEmpty(string)) return null; return Arrays.stream(string.split(SEPARATOR)) .map(s -> Enum.valueOf(enumClass, s)) .collect(Collectors.toList()); } } public class EnumListType extends AbstractSingleColumnStandardBasicType implements DynamicParameterizedType { /** * Here the JavaType is not passed as we don't know yet the enum class. */ public EnumListType() { super(VarcharJdbcType.INSTANCE, null); @Override public String getName() { return "enum_list"; } @Override public String[] getRegistrationKeys() { return new String[] { getName(), "EnumList", EnumSet.class.getName() }; } @Override public void setParameterValues(Properties parameters) { // Here I'm not able to set the JavaType anymore as there is no such method /* String enumClassName = (String) parameters.get("enumClass"); try { setJavaType(new EnumSetJavaType(Class.forName(enumClassName))); } catch (ClassNotFoundException e) {}*/ } The only way I see now is by removing the generic and to define my JavaType as a List. But I hope there is a more clean way of doing this.
Attempt 2
I've then thought about creating a Factory to create the HavaType when needed, by using the annotation @TypeDef. Something like :
public class EnumListTypeFactory implements TypeDef { @Override public Class getTypeClass() { return EnumListType.class; } @Override public String getTypeMethod() { return "forEnumClass"; } public static EnumListType forEnumClass(String enumClassName) { try { Class enumClass = (Class) Class.forName(enumClassName); return new EnumListType(new EnumListJavaType(enumClass)); } catch (ClassNotFoundException e) { throw new HibernateException("Enum class not found", e); } } But in Hibernate 6, the annotation @TypeDef seems to have been removed.
I will be grateful if you have any suggestion about it !
Источник: https://stackoverflow.com/questions/768 ... ernate-6-2
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Как сопоставить набор результатов JDBC с DTO: подход на основе перечислений и общий подход
Anonymous » » в форуме JAVA - 0 Ответы
- 34 Просмотры
-
Последнее сообщение Anonymous
-