Search code examples
cassandradatastaxdatastax-java-driver

java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.util.UUID exception with cassandra?


I have a spring boot java application that talks to cassandra . However one of my queries is failing .

 public class ParameterisedListItemRepository {
    
        private PreparedStatement findByIds;
    
        public ParameterisedListItemRepository(Session session, Validator validator, ParameterisedListMsisdnRepository parameterisedListMsisdnRepository ) {
            this.findByIds =  session.prepare("SELECT * FROM mep_parameterisedListItem WHERE id IN ( :ids )");
    
    
    }
    public List<ParameterisedListItem> findAll(List<UUID> ids){
        
        List<ParameterisedListItem> parameterisedListItemList = new ArrayList<>();

        BoundStatement stmt =this.findByIds.bind();
        stmt.setList("ids", ids);
        session.execute(stmt)
            .all()
            .stream()
            .map(parameterisedListItemMapper)
            .forEach(parameterisedListItemList::add);
        return parameterisedListItemList;
    }
    }

the following is the stack trace

java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.util.UUID
    at com.datastax.driver.core.TypeCodec$AbstractUUIDCodec.serialize(TypeCodec.java:1626)
    at com.datastax.driver.core.AbstractData.setList(AbstractData.java:358)
    at com.datastax.driver.core.AbstractData.setList(AbstractData.java:374)
    at com.datastax.driver.core.BoundStatement.setList(BoundStatement.java:681)
    at com.openmind.primecast.repository.ParameterisedListItemRepository.findAll(ParameterisedListItemRepository.java:128)
    at com.openmind.primecast.repository.ParameterisedListItemRepository$$FastClassBySpringCGLIB$$46ffc15e.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
    at com.openmind.primecast.repository.ParameterisedListItemRepository$$EnhancerBySpringCGLIB$$b2db3c41.findAll(<generated>)
    at com.openmind.primecast.service.impl.ParameterisedListItemServiceImpl.findByParameterisedList(ParameterisedListItemServiceImpl.java:102)
    at com.openmind.primecast.web.rest.ParameterisedListItemResource.getParameterisedListItemsByParameterisedList(ParameterisedListItemResource.java:94)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

Any idea what is going wrong. I know this query is the problem

SELECT * FROM mep_parameterisedListItem WHERE id IN ( :ids )

any idea how I can change the findAll function to achieve the query?

this is the table definition

CREATE TABLE "Openmind".mep_parameterisedlistitem (
    id uuid PRIMARY KEY,
    data text,
    msisdn text,
    ordernumber int,
    parameterisedlist uuid
) WITH COMPACT STORAGE;

Thank you.


Solution

  • Without knowing the table schema, my guess is that a change was made to the table so the schema no longer match the bindings in the prepared statement.

    A big part of the problem is your query with SELECT *. Our recommendation for best practice is to explicitly name all the columns you're retrieving from the table. By specifying the columns in your query, you avoid surprises when the table schema changes.

    In this instance, either a new column was added or an old column was dropped. With the cached prepared statement, it was expecting one column type and got another -- the ArrayList doesn't match UUID.

    The solution is to re-prepare the statement and name all the columns. Cheers!