我有以下实体:
@Entity
@Table(name = "my_entity");
public class MyEntity {
// some fields
@Column(name = "languages")
@Convert(converter = StringToListConverter.class)
private List<String> languages;
}
SQL表:
CREATE TABLE my_entity (
id VARCHAR(255) PRIMARY KEY,
// some fields
languages VARCHAR(255) DEFAULT NULL
);
字段languages
包含用逗号分隔的值列表EN,FR,NO
我的任务是选择包含某种语言的记录。例如,在本机SQL中,我想使用以下SQL:
SELECT * FROM my_entity e WHERE e.languages LIKE CONCAT('%', 'EN', '%');
我尝试使用“规范”来做到这一点:
Specification<MyEntity> specification = (root, query, cb) -> {
final Path<Collection<String>> langs = root.get("languages");
// also I tried root.joinList
return cb.isMember("EN", langs);
};
repository.findAll(specification);
但是我收到以下错误:
unknown collection expression type [org.hibernate.jpa.criteria.path.SingularAttributePath]; nested exception is java.lang.IllegalArgumentException: unknown collection expression type [org.hibernate.jpa.criteria.path.SingularAttributePath]
StringToListConverter
正在关注:
@Converter
public class StringToListConverter implements AttributeConverter<List<String>, String> {
@Override
public String convertToDatabaseColumn(List<String> list) {
if(list==null)
return null;
return String.join(",", list);
}
@Override
public List<String> convertToEntityAttribute(String joined) {
if(joined==null)
return null;
return new ArrayList<>(Arrays.asList(joined.split(",")));
}
}
存储库:
public class MyEntityRepository extends PagingAndSortingRepository<Address, String>, JpaSpecificationExecutor<MyEntity> {
}
如何解决此问题?
答案 0 :(得分:0)
关于此问题,有一个很老的开放式休眠问题:https://hibernate.atlassian.net/browse/HHH-9991
遗憾的是,我发现的唯一解决方法是对实体中的语言使用辅助的只读映射,然后在规范中使用它。
@Entity
@Table(name = "my_entity");
public class MyEntity {
// some fields
@Column(name = "languages")
@Convert(converter = StringToListConverter.class)
private List<String> languages;
@Column(name = "languages", insertable = false, updatable = false)
private String languagesString; //No need for setter
}
条件:
Specification<MyEntity> specification = (root, query, cb) -> {
final Path<String> path = root.get("languagesString");
return cb.like(path, "%EN%");
};
repository.findAll(specification);