参数值与预期类型不匹配 java.util.Set
Parameter value did not match expected type java.util.Set
我有以下实体:
@Entity
public class Person extends BaseEntity {
private static final String PETS_SEPARATOR = ";";
@Id
@Nonnull
private String id;
@Column(name = "pets")
@Convert(converter = StringSetConverter.class)
@Nonnull
private Set<String> pets;
}
而 StringSetConverter 基本上在 String(由 ; 分隔)和 Set 之间进行解析。
请注意,这是继承的代码,我不能轻易更改数据库结构以将宠物关系分开 table。
这会导致数据库中有一个字符串,例如:“DOG;CAT;BIRD”。例如,我想找到所有拥有“CAT”的用户。
所以我尝试了像这样的愚蠢搜索
Specification<UserEntity> petsSpecification =
(root, criteriaQuery, cb) -> {
return cb.like(root.get("pets"), "%CAT%"));
};
这并不优雅,我知道这一点,在这里我们应该考虑分隔符(如果我有另一个动物叫“PERSIAN_CAT”会怎样?)。但无论如何,这是失败的:
Caused by: java.lang.IllegalArgumentException: Parameter value [CAT] did not match expected type [java.util.Set (n/a)]
所以只要我们在 Hibernate 中工作,这似乎是正确的,属性 pets 实际上是一个 Set,而不是一个 String。
但是在查看互联网并查看文档后,我看不到使用 Criteria API 进行此查询的明确方法。我可以使用本机查询来处理 String 而不是 Set 并采用“喜欢”的方法,但我想通过代码来完成,不依赖于数据库技术。
您可以简单地对表达式执行类型转换,返回一个新的表达式对象。
Specification<AttributePerson> rawPetSpecification =
(root, criteriaQuery, cb) -> cb.like(root
.get("pets").as(String.class), "%CAT%");
OR
您可以将 Set<String>
列映射到另一个 String
类型的 属性 中:
@Column(name = "pets", insertable = false, updatable = false)
private String rawPets;
这个属性为insertable = false, updatable = false
的列既不可插入也不可更新,所以它的值不会被持久化,所以你得到的是存储的值。
现在您可以像这样编写查询:
Specification<AttributePerson> rawPetSpecification =
(root, criteriaQuery, cb) ->
cb.like(root.get("rawPets"), "%CAT%");
我有以下实体:
@Entity
public class Person extends BaseEntity {
private static final String PETS_SEPARATOR = ";";
@Id
@Nonnull
private String id;
@Column(name = "pets")
@Convert(converter = StringSetConverter.class)
@Nonnull
private Set<String> pets;
}
而 StringSetConverter 基本上在 String(由 ; 分隔)和 Set 之间进行解析。
请注意,这是继承的代码,我不能轻易更改数据库结构以将宠物关系分开 table。
这会导致数据库中有一个字符串,例如:“DOG;CAT;BIRD”。例如,我想找到所有拥有“CAT”的用户。
所以我尝试了像这样的愚蠢搜索
Specification<UserEntity> petsSpecification =
(root, criteriaQuery, cb) -> {
return cb.like(root.get("pets"), "%CAT%"));
};
这并不优雅,我知道这一点,在这里我们应该考虑分隔符(如果我有另一个动物叫“PERSIAN_CAT”会怎样?)。但无论如何,这是失败的:
Caused by: java.lang.IllegalArgumentException: Parameter value [CAT] did not match expected type [java.util.Set (n/a)]
所以只要我们在 Hibernate 中工作,这似乎是正确的,属性 pets 实际上是一个 Set,而不是一个 String。 但是在查看互联网并查看文档后,我看不到使用 Criteria API 进行此查询的明确方法。我可以使用本机查询来处理 String 而不是 Set 并采用“喜欢”的方法,但我想通过代码来完成,不依赖于数据库技术。
您可以简单地对表达式执行类型转换,返回一个新的表达式对象。
Specification<AttributePerson> rawPetSpecification =
(root, criteriaQuery, cb) -> cb.like(root
.get("pets").as(String.class), "%CAT%");
OR
您可以将 Set<String>
列映射到另一个 String
类型的 属性 中:
@Column(name = "pets", insertable = false, updatable = false)
private String rawPets;
这个属性为insertable = false, updatable = false
的列既不可插入也不可更新,所以它的值不会被持久化,所以你得到的是存储的值。
现在您可以像这样编写查询:
Specification<AttributePerson> rawPetSpecification =
(root, criteriaQuery, cb) ->
cb.like(root.get("rawPets"), "%CAT%");