![](/img/trans.png)
[英]Autogenerate UUID or timeuuid in spring-data Cassandra?
[英]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.