问题
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