[英]Parameter value did not match expected type java.util.Set
I have the following entity:我有以下实体:
@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;
}
And the StringSetConverter basically parses between String (separated by;) and Set. StringSetConverter 基本上在 String(由;分隔)和 Set 之间进行解析。
Notice that this is inherited code and I cannot easily change the database structure to have the pet relations in a separated table.请注意,这是继承的代码,我无法轻易更改数据库结构以将宠物关系放在单独的表中。
This causes having in the database a string like: "DOG;CAT;BIRD".这导致在数据库中有一个字符串,如:“DOG;CAT;BIRD”。 And I want to find all the users that have "CAT", for instance.
例如,我想找到所有拥有“CAT”的用户。
So I tried a silly search like this one所以我尝试了像这样的愚蠢搜索
Specification<UserEntity> petsSpecification =
(root, criteriaQuery, cb) -> {
return cb.like(root.get("pets"), "%CAT%"));
};
This is not elegant, I'm aware of that, and here we should take into account the separator (what happens if I have another animal called "PERSIAN_CAT"?).这并不优雅,我知道这一点,在这里我们应该考虑分隔符(如果我有另一种名为“PERSIAN_CAT”的动物会怎样?)。 But anyway, this is failing with this:
但无论如何,这是失败的:
Caused by: java.lang.IllegalArgumentException: Parameter value [CAT] did not match expected type [java.util.Set (n/a)]
So it seems right as long as we are working in Hibernate, and the attribute pets is in fact a Set, not a String.所以只要我们在 Hibernate 工作就好像是正确的,属性 pets 实际上是一个 Set,而不是一个 String。 But after looking into the inte.net and checking the documentation, I cannot see a clear way of making this query using Criteria API. I could use a native query to work with the String instead of the Set and make the "like" approach, but I would like to do it by code, non-depending in the technology of the database.
但是在查看了 inte.net 并检查了文档之后,我看不到使用 Criteria API 进行此查询的明确方法。我可以使用本机查询来处理 String 而不是 Set 并使用“like”方法,但我想通过代码来完成,不依赖于数据库技术。
You can simply perform a typecast upon the expression, returning a new expression object.您可以简单地对表达式执行类型转换,返回一个新表达式 object。
Specification<AttributePerson> rawPetSpecification =
(root, criteriaQuery, cb) -> cb.like(root
.get("pets").as(String.class), "%CAT%");
OR
You could map the Set<String>
column in another property of String
type:您可以 map
String
类型的另一个属性中的Set<String>
列:
@Column(name = "pets", insertable = false, updatable = false)
private String rawPets;
This column with the attribute insertable = false, updatable = false
as being neither insertable nor updatable, so that its value is not persisted, so you get the stored value.具有属性
insertable = false, updatable = false
的这一列既不可插入也不可更新,因此它的值不会被持久化,所以你得到的是存储的值。 https://stackoverflow.com/a/3805682/2039546 https://stackoverflow.com/a/3805682/2039546
Now you can write a query like this:现在您可以编写这样的查询:
Specification<AttributePerson> rawPetSpecification =
(root, criteriaQuery, cb) ->
cb.like(root.get("rawPets"), "%CAT%");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.