title: About an exception when trying to use a composite primary key with cassandra and spring-data-cassandra
body: <p>I am playing with spring-data and cassandra, seeing how to code a service which has to store data from a REST service within a cassandra ring, no problem about it, but when i try to retrieve data from cassandra, i want to use a composite primary key and i am facing a ClassCastException.</p>
  
  <p>I already saw in a previous <a href="https://stackoverflow.com/questions/34363344/querying-tables-with-composite-primary-keys-using-spring-data-cassandra">post</a> in SO a similar problem, but the solution is not working for me. I already saw <a href="https://stackoverflow.com/questions/43763250/spring-data-rest-with-composite-primary-key">another</a> but this is related to spring-data-cassandra, no spring-data-rest.</p>
  
  <p>This is @Table anotated class:</p>
  
  <pre><code>import org.springframework.data.annotation.CreatedDate;
  import org.springframework.data.annotation.LastModifiedDate;
  import org.springframework.data.cassandra.mapping.PrimaryKey;
  import org.springframework.data.cassandra.mapping.Table;
  import java.time.LocalDateTime;
  import java.util.Map;
  import javax.validation.constraints.NotNull;
  
  @Table(value=AdminUserCassandraTable.tableName)
  public class AdminUserCassandraTable {
  
  @org.springframework.data.annotation.Transient
  public static final String tableName = "AdminUser";
  
  @PrimaryKey
  private AdminUserPK id;
  
  private String tenantId;
  
  private String orgId;
  
  private boolean superAdmin;
  
  @NotNull
  private String password;
  
  private String emailAddress;
  
  
  private Map&lt;String, String&gt; metadata;
  
  @CreatedDate
  private LocalDateTime createdAt;
  
  @LastModifiedDate
  private LocalDateTime lastModified;
  
  public AdminUserCassandraTable() {
      this.id = null;
  }
  
  @Override public String toString() {
      return "AdminUserCassandraTable{" +
              "id=" + id +
              ", tenantId='" + tenantId + '\'' +
              ", orgId='" + orgId + '\'' +
              ", superAdmin=" + superAdmin +
              ", password='" + password + '\'' +
              ", emailAddress='" + emailAddress + '\'' +
              ", metadata=" + metadata +
              ", createdAt=" + createdAt +
              ", lastModified=" + lastModified +
              '}';
  }
  
  ...
  
  }
  </code></pre>
  
  <p>This is AdminUserPK:</p>
  
  <pre><code>import java.io.Serializable;
  import java.util.UUID;
  import org.springframework.cassandra.core.PrimaryKeyType;
  import org.springframework.data.cassandra.mapping.CassandraType;
  import org.springframework.data.cassandra.mapping.PrimaryKeyClass;
  import org.springframework.data.cassandra.mapping.PrimaryKeyColumn;
  import com.datastax.driver.core.DataType;
  
  
  @PrimaryKeyClass
  public class AdminUserPK implements Serializable{
  
  @PrimaryKeyColumn(name = "id", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
  @CassandraType(type = DataType.Name.UUID)
  private UUID id;
  
  @PrimaryKeyColumn(name = "username", ordinal = 1, type = PrimaryKeyType.PARTITIONED)
  @CassandraType(type = DataType.Name.TEXT)
  private String username;
  
  // https://stackoverflow.com/questions/34363344/querying-tables-with-composite-primary-keys-using-spring-data-cassandra
  public AdminUserPK() {
      this.id = null;
      this.username = null;
  }
  
  public AdminUserPK(UUID id, String username) {
      this.id = id;
      this.username = username;
  }
  ...
  getters, setters, equals and hashCode methods.
  }
  </code></pre>
  
  <p>This is AdminUserRepository:</p>
  
  <pre><code>import java.util.Optional;
  import java.util.UUID;
  import org.springframework.data.cassandra.repository.CassandraRepository;
  import org.springframework.data.cassandra.repository.Query;
  import org.springframework.data.cassandra.repository.TypedIdCassandraRepository;
  import unicon.matthews.admin.AdminUser;
  import unicon.matthews.admin.service.AdminUserCassandraTable;
  import unicon.matthews.admin.service.AdminUserPK;
  
  public interface AdminUserRepository extends TypedIdCassandraRepository&lt;AdminUserCassandraTable, AdminUserPK&gt; {
  
  **The problem must be here, with this @Query.**
  @Query("select * from AdminUser where id = ?0 and username = ?1")
  Optional&lt;AdminUser&gt; findByIdAndUsername(final UUID id,final String userName);
  
  }
  </code></pre>
  
  <p>And finally the test case that provokes the exception:</p>
  
  <pre><code>import static org.hamcrest.Matchers.hasItems;
  import static org.hamcrest.Matchers.is;
  import static org.junit.Assert.assertEquals;
  import static org.junit.Assert.assertNotNull;
  import static org.junit.Assert.assertThat;
  import static org.junit.Assert.assertTrue;
  import java.time.LocalDateTime;
  import java.util.HashMap;
  import java.util.Map;
  import java.util.Optional;
  import java.util.UUID;
  import java.util.stream.Collectors;
  import java.util.stream.Stream;
  import org.junit.Before;
  import org.junit.ClassRule;
  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.boot.test.context.SpringBootTest;
  import org.springframework.data.util.Version;
  import org.springframework.test.context.junit4.SpringRunner;
  import example.springdata.cassandra.util.CassandraKeyspace;
  import unicon.matthews.admin.AdminUser;
  import unicon.matthews.admin.service.AdminUserCassandraTable;
  import unicon.matthews.admin.service.AdminUserPK;
  import unicon.matthews.admin.service.repository.AdminUserRepository;
  
  @RunWith(SpringRunner.class)
  @SpringBootTest(classes = unicon.matthews.admin.service.repository.CassandraConfiguration.class)
  public class AdminUserRepositoryTests {
  
      final String userName = UUID.randomUUID().toString();
      final UUID _id = UUID.randomUUID();
  
  
      @ClassRule public final static CassandraKeyspace CASSANDRA_KEYSPACE = CassandraKeyspace.onLocalhost().atLeast(Version.parse("3.0"));
  
      @Autowired AdminUserRepository repository;
  
      @Before
      public void setUp() throws Exception {
  
          repository.deleteAll();
          AdminUserCassandraTable aPojo = new AdminUserCassandraTable();
          AdminUserPK adminUserPK = new AdminUserPK();
          adminUserPK.setId(_id);
          adminUserPK.setUsername(userName);
          aPojo.setId(adminUserPK);
          aPojo.setEmailAddress("some@company.com");
          aPojo.setOrgId("orgId");
          aPojo.setPassword("pass");
          aPojo.setTenantId("tenantId");
          aPojo.setCreatedAt(LocalDateTime.now());
          aPojo.setLastModified(null);
          // OJITO! metadatos a null...
          aPojo.setMetadata(null);
          aPojo.setSuperAdmin(Boolean.FALSE);
          repository.save(aPojo);
          assertTrue(repository.count() &gt; 0);
      }
  
  
      @Test
      public void testFindByIdAndUsername() {
  
          Optional&lt;AdminUser&gt; loadedUserName = repository.findByIdAndUsername(_id,userName);
          assertNotNull(loadedUserName);
          assertEquals("something went wrong!",userName,loadedUserName.get().getUsername());
      }
  }
  </code></pre>
  
  <p>The exception is:</p>
  
  <pre><code>java.lang.ClassCastException: Cannot cast unicon.matthews.admin.service.AdminUserPK to java.lang.String
  at java.lang.invoke.MethodHandleImpl.newClassCastException(MethodHandleImpl.java:361)
  at java.lang.invoke.MethodHandleImpl.castReference(MethodHandleImpl.java:356)
  at unicon.matthews.admin.AdminUser_Accessor_cmi9qy.setProperty(Unknown Source)
  at org.springframework.data.cassandra.repository.query.DtoInstantiatingConverter$2.doWithPersistentProperty(DtoInstantiatingConverter.java:101)
  at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:346)
  at org.springframework.data.cassandra.repository.query.DtoInstantiatingConverter.convert(DtoInstantiatingConverter.java:92)
  at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:221)
  at org.springframework.data.repository.query.ResultProcessor$ChainingConverter$1.convert(ResultProcessor.java:209)
  at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:221)
  at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:162)
  at org.springframework.data.cassandra.repository.query.CassandraQueryExecution$ResultProcessingConverter.convert(CassandraQueryExecution.java:178)
  at org.springframework.data.cassandra.repository.query.CassandraQueryExecution$ResultProcessingExecution.execute(CassandraQueryExecution.java:143)
  at org.springframework.data.cassandra.repository.query.AbstractCassandraQuery.execute(AbstractCassandraQuery.java:113)
  at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:483)
  at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
  at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
  at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
  at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
  at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
  at com.sun.proxy.$Proxy96.findByIdAndUsername(Unknown Source)
  at unicon.mattheews.admin.service.repository.test.AdminUserRepositoryTests.testFindByIdAndUsername(AdminUserRepositoryTests.java:120)
  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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
  at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
  at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
  at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
  at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
  at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
  at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
  at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
  at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
  at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
  at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
  at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
  at org.junit.rules.RunRules.evaluate(RunRules.java:20)
  at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
  </code></pre>
  
  <p>The problem must be related with AdminUserRepository interface, with @Query, but how can i pass the UUID and the String that compounds the primary key coming from parameters to the final primary key that spring-data-cassandra needs?</p>