Skip to content

Spring Data Elasticsearch: ClassCastException thrown in existsBy* repository method #2162

Closed
@stsypanov

Description

@stsypanov

I've got this trivial index in ES:

{
  "dynamic": "strict",
  "properties": {
    "_class": {
      "type": "text",
      "fields": {
        "keyword": {
          "type": "keyword"
        }
      }
    },
    "id": {
      "type": "keyword"
    },
    "reviewRequestDocumentId": {
      "type": "keyword"
    },
    "productId": {
      "type": "keyword"
    }
  }
}

To work with it I use Spring Data Elasticsearch, so an entity and bound repository are created:

@Data
@Builder(toBuilder = true)
@Document(indexName = "order_line", createIndex = false)
public class OrderLineDocument {

    @Id
    private String id;

    @NotNull
    private String reviewRequestDocumentId;

    @NotNull
    private String productId;
}

public interface OrderLineRepository extends ElasticsearchRepository<OrderLineDocument, String> {

    boolean existsByReviewRequestDocumentIdAndProductId(String reviewRequestDocumentId, String productId);

}

The problem I'm facing is related to repository method existsByReviewRequestDocumentIdAndProductId() which is called from test method:

@Test
void existsByReviewRequestDocumentIdAndProductId() {
    String rrdId = UUID.randomUUID().toString();
    String productId = UUID.randomUUID().toString();

    OrderLineDocument orderLine = OrderLineDocument.builder()
            .productId(productId)
            .reviewRequestDocumentId(rrdId)
            .build();

    String id = repository.save(orderLine).getId();

    assertThat(repository.findById(id)).isNotEmpty();

    assertThat(repository.existsByReviewRequestDocumentIdAndProductId(rrdId, productId)).isTrue();
}

Calling it results in ClassCastException with this stack trace:

java.lang.ClassCastException: class com.yotpo.review.requests.dashboard.core.documents.orderline.OrderLineDocument cannot be cast to class java.lang.Boolean (com.yotpo.review.requests.dashboard.core.documents.orderline.OrderLineDocument is in unnamed module of loader 'app'; java.lang.Boolean is in module java.base of loader 'bootstrap')

	at com.sun.proxy.$Proxy140.existsByReviewRequestDocumentIdAndProductId(Unknown Source)
	at com.yotpo.review.requests.dashboard.componenttest.OrderLineRepositoryTest.existsByReviewRequestDocumentIdAndProductId(OrderLineRepositoryTest.java:67)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)

It looks like the method queries the whole entity from ES instead of fetching simple boolean.

Does anyone aware of such issues? Is it a bug or have I misconfigured something?

P.S. I've tried also

public interface OrderLineRepository extends ElasticsearchRepository<OrderLineDocument, String> {

    boolean existsOrderLineDocumentByReviewRequestDocumentIdAndProductId(String reviewRequestDocumentId, String productId);

}

and

public interface OrderLineRepository extends ElasticsearchRepository<OrderLineDocument, String> {

    boolean existsOrderLineByReviewRequestDocumentIdAndProductId(String reviewRequestDocumentId, String productId);

}

same exception is thrown.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions