Home > Blockchain >  Spring data elasticsearch 4.1
Spring data elasticsearch 4.1

Time:10-27

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)

  • Related