Reputation: 305
Entity
@Builder
@Getter @Setter
@ToString(doNotUseGetters = true)
@EqualsAndHashCode(doNotUseGetters = true)
@Table(value = "entity")
public class Entity implements Serializable {
@PrimaryKeyColumn(name = "id", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
@CassandraType(type = DataType.Name.UUID)
private UUID Id;
@Column("list_name")
@CassandraType(type = DataType.Name.TEXT)
private String name;
@Column("type")
@CassandraType(type = DataType.Name.TINYINT)
private Byte type;
Entity Repo
@Repository
public interface EntityRepo extends BaseRepo<Entity, UUID> {
@Query("SELECT * FROM entity WHERE id IN (:id)")
Collection<ListEntity> findByIds(@Param("id") Collection<UUID> listIds);
@Query("SELECT * FROM entity WHERE list_id = :id")
ListEntity findById(@Param("id") UUID id);
}
Query
listRepo.findByListId(UUIDs.random())
listRepo.findByListIds(Arrays.asList(UUIDs.random())
Both results in
CassandraInvalidQueryException/InvalidQueryException
org.springframework.data.cassandra.CassandraInvalidQueryException: Query; CQL
[SELECT * FROM lists WHERE list_id IN (?)]; UUID should be 16 or 0 bytes (20);
nested exception is com.datastax.driver.core.exceptions.`InvalidQueryException: UUID should be 16 or 0 bytes (20)
Anything missing here? Can somebody help?
Upvotes: 1
Views: 3099
Reputation: 1147
I hope you found an answer, but if you are using UUID version 4, maybe the type in your table are wrong. For example instead of UUID your ID field could be varchar.
Upvotes: 1
Reputation: 556
(I am adding this answer for future reference)
I had the same error when running a spark application.
The error occurred when executing a Cassandra query and where a UUID type was expected, some other data type was sent by the query. In my case, it was a String. Passing the right data type (UUID instead of String) resolved the issue.
Upvotes: 1
Reputation: 1092
It is work at me.
Use: findAllBy[object-property]In where [object-property] is name of property of the MyModel UUID.
@Table("example")
public class MyModel {
@PrimaryKeyColumn(name = "uuid", type = PrimaryKeyType.PARTITIONED)
private UUID uuid;
@Column("...")
...
}
public interface MyRepository extends CassandraRepository<MyModel, UUID> {
List<Restaurant> findAllByUuidIn(Collection<UUID> uuidButIfYouWant);
}
// It is OK
return this.myRepository.findAllByUuidIn(Set.of(
UUID.randomUUID(),
UUID.randomUUID()
));
// Throw Error: no viable alternative at input '<EOF>' (SELECT * FROM example WHERE [uuid] IN...)
return this.myRepository.findAllByUuidIn(Set.of());
So if not contain uuid:
Collection<UUID> search = Set.of();
if(search.size() == 0) {
return List.of();
}
return this.myRepository.findAllByUuidIn(search);
Upvotes: 1
Reputation: 18127
It looks like as if IN
queries using UUID are not possible by passing in a collection into a single bind value.
Here's what happens:
Spring Data transforms your String-query
SELECT * FROM entity WHERE id IN (:id)
into Cassandra's notation using positional query arguments
SELECT * FROM entity WHERE id IN (?)
and binds the given parameter to ?
. Let's transform this into an executable piece of code:
session.execute(new SimpleStatement("SELECT * FROM entity WHERE id IN (?)",
Arrays.asList(UUIDs.random())));
When you run this snipped, then you'll end up with InvalidQueryException
again. We can still make an IN
query happen, but we need to unfold parameters:
new SimpleStatement("SELECT * FROM entity WHERE id IN (?, ?)", UUIDs.random(), UUIDs.random())
In an ideal world, Cassandra could accept a List
(or Set
) of items to keep the query string agnostic against the actual number of arguments.
Upvotes: 1