JavaTypeDescriptorRegistry - Не удалось найти подходящий дескриптор типа для запрошенного класса Java
У меня есть проект без проблем, кроме этого предупреждающего сообщения:
WARN org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry - Could not find matching type descriptor for requested Java class [java.util.List]; using fallback enviroment
Почему я получаю это сообщение? Как я могу отключить его?
Я использую:
spring webmvc 4.2.1
hibernate-core 5.0.1
Это сообщение появляется, так как я использую JPA 2.1 AttributeConverter.
Ответы
Ответ 1
Вы получите это предупреждение, если тип конвертера, который должен конвертировать, не реализует Serializable
, не является enum
и одним из типов Hibernate знает, как конвертировать. Как только вы сделаете тип конвертера, который должен конвертировать Serializable
, предупреждение уходит.
Просматривая код Hibernate, цель JavaTypeDescriptor
заключается в предоставлении информации о том, как сериализовать определенные типы и как можно делать глубокие копии. Поскольку Hibernate ничего не знает о типе, он делает некоторые догадки. Если вам нравится, вы можете помочь Hibernate, предоставив JavaTypeDescriptor
себе. Для этого существует Singleton.
Ответ 2
Начиная с Hibernate 5.2.7 (24 января 2017 года) это предупреждение изменилось на:
WARN org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry - HHH000481: Определенный тип Java [класс SomeClass], для которого мы не смогли найти JavaTypeDescriptor и не реализовать equals и/или hashCode. Это может привести к значительным проблемы производительности при выполнении проверки равенства/грязной этот тип Java. Рассмотрите возможность регистрации пользовательского JavaTypeDescriptor или по крайней мере, реализация equals/hashCode.
Итак, есть следующие решения:
1) Убедитесь, что ваш тип реализует equals
и hashcode
, а также аннотирует его с помощью Immutable.class
в случае, если он является неизменным. Hibernate будет использовать резервную копию (указанный здесь).
2) Внедрите определенный дескриптор java-типа, например SomePersistentClassTypeDescriptor
:
JavaTypeDescriptorRegistry.INSTANCE
.addDescriptor(new SomePersistentClassTypeDescriptor());
Вы можете расширить AbstractTypeDescriptor
. Пример, если ваш тип неизменен:
public class SomePersistentClassTypeDescriptor
extends AbstractTypeDescriptor<SomePersistentClass> {
public SomePersistentClassTypeDescriptor() {
super(SomePersistentClass.class);
}
@Override
public String toString(SomePersistentClassvalue) {
return (value == null) ? null : value.toString();
}
@Override
public SomePersistentClassfromString(String string) {
return (string == null) ? null : SomePersistentClass.getInstance(string);
}
@Override
public <X> X unwrap(SomePersistentClass value, Class<X> type, WrapperOptions options) {
if (value == null) return null;
else if (String.class.isAssignableFrom(type)) {
return (X)value.toString();
}
else throw unknownUnwrap(type);
}
@Nullable
@Override
public <X> SomePersistentClass wrap(X value, WrapperOptions options)
{
if (value == null) return null;
if (String.class.isInstance(value)) {
return SomePersistentClass.getInstance(((String)value));
}
throw unknownWrap(value.getClass());
}
}
Если ваш тип, однако, изменен, укажите свой MutabilityPlan
:
public class SomePersistentClassTypeDescriptor
extends AbstractTypeDescriptor<SomePersistentClass> {
public SomePersistentClassTypeDescriptor() {
super(SomePersistentClass.class, new MyMutabilityPlan());
}
...
}
3) Сделайте SomePersistentClass
реализацией Serializable. Тогда Hibernate будет использовать сравнение массива байтов сериализованного объекта для грязной проверки и т.д., Что не очень приятно.
Также см.: