JavaTypeDescriptorRegistry - Could not find matching type descriptor for requested Java class

时光怂恿深爱的人放手 提交于 2020-01-13 07:26:18

问题


I have a project running with no problem except this warning message:

WARN  org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry - Could not find matching type descriptor for requested Java class [java.util.List]; using fallback enviroment

Why am I getting this message? How can I disable it?

I'm using:

spring webmvc 4.2.1
hibernate-core 5.0.1

This message appears since I'm using JPA 2.1 AttributeConverter.


回答1:


You get this warning if the type your converter is supposed to convert does not implement Serializable, is not an enum nor one of the types Hibernate knows how to convert. As soon as you make the type your converter is supposed to convert Serializable, the warning goes away.

Looking through the Hibernate code, the purpose of a JavaTypeDescriptor seems to be to provide information on how to serialize certain types and whether or how it's possible to do deep copies. Because Hibernate doesn't know anything about the type, it makes some guesses. If you like, you can help Hibernate by supplying a JavaTypeDescriptor yourself. There's a Singleton for that.




回答2:


While both the answers are logical and correct none address the actual issue in the question above!

You are getting this error for java.util.List, neither can you write equals/hashcode implementations, nor extend Serializable, and defining a AbstractTypeDescriptor is pointless here.

You are getting this error simply because interface List is not Serializable in Java and you will have to choose an implementation which is.

The concrete types like ArrayList and LinkedList are Serializable, you can either use them (breaking interface-based programming) or create your own List implementations that extend/implement Serializable (none of the built-in concrete List implementations can be used then).




回答3:


As of Hibernate 5.2.7 (Jan 24th, 2017) this warning changed to:

WARN org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry - HHH000481: Encountered Java type [class SomeClass] for which we could not locate a JavaTypeDescriptor and which does not appear to implement equals and/or hashCode. This can lead to significant performance problems when performing equality/dirty checking involving this Java type. Consider registering a custom JavaTypeDescriptor or at least implementing equals/hashCode.

So, there are these solutions:

1) Make sure your type implements equals and hashcode, and also annotate it with Immutable.class in case it is immutable. Hibernate will use the fallback (defined here).

2) Implement a specific java-type-descriptor, like SomePersistentClassTypeDescriptor:

JavaTypeDescriptorRegistry.INSTANCE
                          .addDescriptor(new SomePersistentClassTypeDescriptor());

You can extend AbstractTypeDescriptor. An example if your type is immutable:

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());
        }
    }

If your type, however, is mutable, provide your own MutabilityPlan:

public class SomePersistentClassTypeDescriptor
      extends AbstractTypeDescriptor<SomePersistentClass> {

    public SomePersistentClassTypeDescriptor() {
        super(SomePersistentClass.class, new MyMutabilityPlan());
        }
...
}

3) Make SomePersistentClass implement Serializable. Then Hibernate will use byte array comparison of the serialized object for dirty checking etc, which is not very nice.


Also, see:

  • https://hibernate.atlassian.net/browse/HHH-10858

  • https://hibernate.atlassian.net/browse/HHH-11391 (for the future Hibernate 6.0).



来源:https://stackoverflow.com/questions/32795355/javatypedescriptorregistry-could-not-find-matching-type-descriptor-for-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!