2015-04-02 1 views
8

J'essaie d'interroger une table Cassandra en utilisant la clause IN et l'annotation @Query de Spring Data. J'ai une table avec une clé de partition de last_name et une clé de clustering de first_name.Clause IN avec Spring Data et Cassandra @Query

J'ai cette requête de travail

@Query("SELECT * FROM people WHERE last_name=?0") 
public List<People> findByLastName(String lastName); 

et je voudrais faire quelque chose comme

@Query("SELECT * FROM people WHERE last_name=?0 AND first_name IN ?1") 
public List<People> findByLastName(String lastName, String[] firstName); 

Je l'ai travail à l'aide

CassandraOperations.select("SELECT * FROM people WHERE last_name=" + lastName + 
" AND first_name IN (" + concatinatedNameList + ")", People.class); 

Mais pour un certain nombre de raisons (style de code, test, je jure qu'il y en a plus) Je préférerais utiliser @Query. Des idées?

MODIFIEZ POUR PLUS D'INFO!

passage dans un tableau, ensemble, ou liste retourne Caused by: java.lang.IllegalArgumentException: encountered unsupported query parameter type [class [Ljava.lang.String;] in method public abstract

a également essayé:

String firstName = "Joe,Jim"; 
@Query("SELECT * FROM people WHERE last_name=?0 AND first_name IN (?1)") 
public List<People> findByLastName(String lastName, String firstName); 

Rien trouvé, la recherche de la bibliothèque pour une personne seule avec un nom concatinated ('Joe,Jim')

String firstName = "'Joe','Jim'"; 
@Query("SELECT * FROM people WHERE last_name=?0 AND first_name IN (?1)") 
public List<People> findByLastName(String lastName, String firstName); 

Rien trouvé, la requête est échappée et se termine ('''Joe'',''Jim''')

String firstName = "Joe','Jim"; // Hoping the library would just add the outer quotes, getting desperate 
@Query("SELECT * FROM people WHERE last_name=?0 AND first_name IN (?1)") 
public List<People> findByLastName(String lastName, String firstName); 

Pour l'instant, la demande est échappé et finit par ('Joe'',''Jim')

+1

Avez-vous essayé un type de collection? Définir ou liste de chaînes au lieu de tableau de chaînes? –

+0

Les listes et les ensembles renvoient une erreur similaire à celle au démarrage 'Causée par: java.lang.IllegalArgumentException: rencontré le type de paramètre de requête non pris en charge [interface java.util.Set] ' –

Répondre

8

Vous devez utiliser Brassards lorsque vous utilisez IN.

@Query("SELECT * FROM people WHERE last_name=?0 AND first_name IN (?1)") 
public List<People> findByLastName(String lastName, String[] firstName); 

Mais il y a d'autres problèmes dans votre code. Je les ai tous remplacés par de bonnes normes de codage comme ci-dessous. Y compris mon favori personnel d'utiliser des paramètres nommés.

@Query("SELECT p FROM People p WHERE p.lastName = :lastName AND p.firstName IN (:firstNames)") 
public List<People> findByName(@Param("lastName") String lastName, @Param("firstNames") String[] firstNames); 
+0

Je voudrais pouvoir utiliser des paramètres nommés, mais comme je passe effectivement à 7, je me retrouve avec l'exception" Invalid amount of bind variable ". Je suis en mesure de le faire fonctionner en passant dans une seule chaîne à contraindre, mais lors du passage dans un tableau, je vois cela au démarrage 'Causée par: java.lang.IllegalArgumentException: rencontré le type de paramètre de requête non pris en charge [class [Ljava .lang.String;] ' –

+1

Alors pouvez-vous essayer le premier. votre même requête avec des bretelles. Comme 'IN (? 1)' –

+0

Si je passe un nom unique, cela fonctionne. Si je passe plusieurs, il est entouré de guillemets donc la requête finit par 'IN ('Joe, Jim')'. Évidemment, personne n'est nommé 'Joe, Jim'. J'ai aussi essayé de construire une chaîne de requête, '' Joe '', 'Jim', mais quand elle est passée dans la bibliothèque échappe toutes les citations et je me retrouve avec '' '' Joe '', '' Jim '' '' –

2

Cela ne semble pas possible!

J'ai vérifié le code source de spring-data-cassandra-1.3.2.RELEASE.jar. Les types de données autorisés du paramètre dans la méthode de requête sont String.class, CharSequence.class, char.class, Character.class, char[].class, long.class, Long.class, boolean.class, Boolean.class, BigDecimal.class, BigInteger.class, double.class, Double.class, float.class, Float.class, InetAddress.class, Date.class, UUID.class, int.class are Integer.class.

Ils se trouvent dans

org.springframework.data.cassandra.repository.query.CassandraQueryMethod.ALLOWED_PARAMETER_TYPES = Collections.unmodifiableList(Arrays 
      .asList(new Class<?>[] { String.class, CharSequence.class, char.class, Character.class, char[].class, long.class, 
        Long.class, boolean.class, Boolean.class, BigDecimal.class, BigInteger.class, double.class, Double.class, 
        float.class, Float.class, InetAddress.class, Date.class, UUID.class, int.class, Integer.class })); 

Si nous passons les types de données autres que ceux-ci, puis org.springframework.data.cassandra.repository.query.CassandraQueryMethod.verify(Method method, RepositoryMetadata metadata) jetteront IllegalArgumentException.