簡體   English   中英

Spring Data Cassandra:InvalidQueryException:UUID 應為 16 或 0 字節 (20)

[英]Spring Data Cassandra: InvalidQueryException: UUID should be 16 or 0 bytes (20)

實體

@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;

實體回購

@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);

}  

詢問

listRepo.findByListId(UUIDs.random())
listRepo.findByListIds(Arrays.asList(UUIDs.random())

兩者都導致

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)

這里有什么遺漏嗎? 有人可以幫忙嗎?

我希望您找到了答案,但如果您使用的是 UUID 版本 4,那么您的表中的類型可能有誤。 例如,您的 ID 字段可以是 varchar,而不是 UUID。

通過將集合傳遞到單個綁定值中,使用 UUID 的IN查詢似乎是不可能的。

這是發生的事情:

Spring Data 轉換您的字符串查詢

SELECT * FROM entity WHERE id IN (:id)

使用位置查詢參數轉換為 Cassandra 的符號

SELECT * FROM entity WHERE id IN (?)

並將給定的參數綁定到? . 讓我們把它轉換成一段可執行的代碼:

session.execute(new SimpleStatement("SELECT * FROM entity WHERE id IN (?)",
                                     Arrays.asList(UUIDs.random())));

當您運行此InvalidQueryException時,您將再次InvalidQueryException 我們仍然可以進行IN查詢,但我們需要展開參數:

new SimpleStatement("SELECT * FROM entity WHERE id IN (?, ?)", UUIDs.random(), UUIDs.random())

在理想的世界中,Cassandra 可以接受一個List (或Set )項目,以保持查詢字符串與實際參數數量無關。

這是我的工作。

使用: findAllBy[object-property]其中 [object-property] 是 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());

因此,如果不包含 uuid:

Collection<UUID> search = Set.of();

if(search.size() == 0) {
    return List.of();
}

return this.myRepository.findAllByUuidIn(search);

(我正在添加此答案以供將來參考)

運行 spark 應用程序時我遇到了同樣的錯誤。

執行 Cassandra 查詢時發生錯誤,並且在需要 UUID 類型的地方,查詢發送了一些其他數據類型。 就我而言,它是一個字符串。 傳遞正確的數據類型(UUID 而不是 String)解決了這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM