Issue after upgrading to spring boot 2.3 and spring data elasticsearch 4.0.9. I have a document like this:
public class Entity implements Serializable {
@Id private String id;
private URL url;
...
}
Thi was working fine with spring data 3.0 with Jackson, but after upgrading to 4.0 Jackson is no longer available and now I'm getting an instantiation exception from spring failing to instantiate the URL object.
Exception:
org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate java.net.URL using constructor NO_CONSTRUCTOR with arguments
at org.springframework.data.mapping.model.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:65)
at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:87)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.readEntity(MappingElasticsearchConverter.java:178)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.readMapValue(MappingElasticsearchConverter.java:375)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.readValue(MappingElasticsearchConverter.java:296)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter$ElasticsearchPropertyValueProvider.getPropertyValue(MappingElasticsearchConverter.java:915)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.readProperties(MappingElasticsearchConverter.java:253)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.readEntity(MappingElasticsearchConverter.java:185)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.read(MappingElasticsearchConverter.java:165)
at org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter.read(MappingElasticsearchConverter.java:74)
at org.springframework.data.elasticsearch.core.AbstractElasticsearchTemplate$ReadDocumentCallback.doWith(AbstractElasticsearchTemplate.java:602)
at org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate.get(ElasticsearchRestTemplate.java:166)
at org.springframework.data.elasticsearch.repository.support.AbstractElasticsearchRepository.findById(AbstractElasticsearchRepository.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.data.repository.core.support.ImplementationInvocationMetadata.invoke(ImplementationInvocationMetadata.java:72)
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:382)
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:205)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:550)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:155)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy176.findById(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy176.findById(Unknown Source)
at com.callfire.starters.elasticsearch.starter.store.AbstractGenericElasticSearchMapStore.load(AbstractGenericElasticSearchMapStore.java:153)
at com.callfire.starters.elasticsearch.starter.store.AbstractGenericElasticSearchMapStore.load(AbstractGenericElasticSearchMapStore.java:50)
at com.hazelcast.map.impl.MapStoreWrapper.load(MapStoreWrapper.java:165)
at com.hazelcast.map.impl.mapstore.writebehind.WriteBehindStore.load(WriteBehindStore.java:206)
at com.hazelcast.map.impl.mapstore.writebehind.WriteBehindStore.load(WriteBehindStore.java:56)
at com.hazelcast.map.impl.recordstore.DefaultRecordStore.putIfAbsent(DefaultRecordStore.java:1004)
at com.hazelcast.map.impl.operation.PutIfAbsentOperation.run(PutIfAbsentOperation.java:36)
at com.hazelcast.spi.Operation.call(Operation.java:170)
at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.call(OperationRunnerImpl.java:210)
at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:199)
at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:147)
at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:125)
at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.run(OperationThread.java:110)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [java.net.URL]: No default constructor found; nested exception is java.lang.NoSuchMethodException: java.net.URL.<init>()
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:146)
at org.springframework.data.mapping.model.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:62)
... 54 common frames omitted
Caused by: java.lang.NoSuchMethodException: java.net.URL.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getDeclaredConstructor(Class.java:2178)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:139)
... 55 common frames omitted
Any ideas on resolution appreciated.
CodePudding user response:
This is because you might not have any constructor that instantiates with URL as a parameter.
In your case, the constructor should be like.
public Entity(URL url, ** **) {
this.url = url;
**;
**;
}
Also, you can use Lombok to get constructor functionality with annotations like @NoArgsConstructor, @AllArgsConstructor, @Data just add this to your model class it will work.
CodePudding user response:
From the data that is in the index it looks like the URL was stored as a nested object url
with the properties protocol
, host
, port
, file
, authority
, path
, handler
(which itself is an object).
On reading Spring Data Elasticsearch tries to create an object of the class URL
in order to set these properties on the object. But the URL
class does not have a constructor to do this.
To read that in, you will need to define a custom converter that can read and write an URL to a Document
object (which is basically a Map<String, Object>
and register that converter (see https://docs.spring.io/spring-data/elasticsearch/docs/4.2.5/reference/html/#elasticsearch.mapping.meta-model.conversions)