2015-09-26 131 views
12
匹配

类型描述我有一个项目,除了此警告消息没有问题的运行: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 

为什么会收到这个消息?我该如何禁用它?

我使用的是:因为我使用JPA 2.1 AttributeConverter出现

spring webmvc 4.2.1 
hibernate-core 5.0.1 

此消息。

+1

具有相同的问题;我使用了10多个AttributeConverters,但其中只有两个似乎受到影响。另一个AttributeConverters从简单类型转换为数据库列(例如数组),但是这两个使用复杂类型(例如POJO)来进行字符串(Json)转换。 – krisy

回答

8

如果你的转换器应该转换的类型不执行Serializable,那么你会得到这个警告,不是enum也不是one of the types Hibernate知道如何转换。只要你的类型转换器应该转换为Serializable,警告消失。

翻阅Hibernate代码,JavaTypeDescriptor的目的似乎是提供有关如何序列化某些类型以及是否或如何可以执行深度复制的信息。因为Hibernate不知道类型的任何信息,所以it makes some guesses。如果你喜欢,你可以通过自己提供JavaTypeDescriptor来帮助Hibernate。这有一个Singleton

+1

只是简单地使'Serializable'类型能够让Hibernate使用字节数组比较序列化对象来进行脏检查(等等)。所以一定要知道你在做什么。 – sfussenegger

3

作为休眠5.2.7的(2017年1月24日)此警告更改为:

WARN org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry - HHH000481:遇到Java类型[类SomeClass的]其中 我们找不到一个JavaTypeDescriptor,而哪一个没有出现在 实现equals和/或hashCode。当执行包含此Java类型的 的相等/脏检查时,这可能会导致显着的性能问题 。考虑注册一个自定义的JavaTypeDescriptor或至少实现equals/hashCode的 。

因此,有这些解决方案:

1)确保您的类型实现equalshashcode,同时还与Immutable.class的情况下,它是不可改变的注释吧。休眠将使用后备(defined here)。

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会使用序列化对象的字节数组比较来进行脏检等,这不是很好。


此外,见:

1

虽然两者的答案都是合乎逻辑的和正确的地址没有在上面的问题的实际问题!

您收到此错误java.util.List,你也不能写等号/哈希代码的实现,也不延长Serializable,并定义AbstractTypeDescriptor是没有意义在这里。

因为Java中的接口列表不是Serializable,所以您将不得不选择一个实现。

的具体类型,如ArrayListLinkedListSerializable,您可以使用它们(突破基于接口的编程),或者创建自己的列表实现扩展/实现Serializable(无内置混凝土List实现可以使用然后)。