Postgresql JPA/Hibernate自定义查询和Postgres枚举列表
我有一个实体Postgresql JPA/Hibernate自定义查询和Postgres枚举列表,postgresql,hibernate,jpa,kotlin,enums,Postgresql,Hibernate,Jpa,Kotlin,Enums,我有一个实体Company,其类型由enumCompanyType表示。 数据库是Postgres,在那里表示为枚举类型。 我使用JPA/Hibernate及其存储库。 请注意,我是JPA、Hibernate和Kotlin的新手 我正在尝试创建自定义的@Query,在这里我需要选择类型(枚举)在可能类型列表中的公司。然而,在SQL中的类型转换和/或@Query的语法方面,我遇到了各种错误 Kotlin中数据类公司的主要部分(未复制任何其他属性,包括id): Kotlin中的枚举CompanyTy
Company
,其类型由enumCompanyType
表示。
数据库是Postgres,在那里表示为枚举类型。
我使用JPA/Hibernate及其存储库。
请注意,我是JPA、Hibernate和Kotlin的新手
我正在尝试创建自定义的@Query
,在这里我需要选择类型(枚举)在可能类型列表中的公司。然而,在SQL中的类型转换和/或@Query
的语法方面,我遇到了各种错误
Kotlin中数据类公司的主要部分(未复制任何其他属性,包括id):
Kotlin中的枚举CompanyType
:
enum class CompanyType(value: Int) {
BUSINESS(1),
TOWN(2),
NONPROFIT(3),
RESEARCH(4),
OTHER(5)
}
Postgres中的枚举公司类型
:
CREATE TYPE public.company_type AS ENUM (
'BUSINESS',
'TOWN',
'NONPROFIT',
'RESEARCH',
'OTHER'
);
CREATE CAST (character varying AS public.company_type) WITH INOUT AS ASSIGNMENT;
JPA存储库与我的初始尝试:
@Repository
interface CompanyDAO : PagingAndSortingRepository<Company> {
@Query("SELECT c FROM #{#entityName} c " +
"WHERE c.type IN ?1"
)
fun findAllByTypeIn(types: List<CompanyType>, pageable: Pageable): Page<Company>
}
所以我试着去投,但不知道到底是怎么投的
@Query("SELECT c FROM #{#entityName} c " +
"WHERE c.type IN cast(?1 AS company_type[])"
)
导致编译时出错:
antlr.MismatchedTokenException: expecting EOF, found ')'
努力
@Query("SELECT c FROM #{#entityName} c " +
"WHERE c.type IN ?1\\:\\:company_type[]"
)
导致
org.hibernate.QueryException: unexpected char: '\'
如何创建这样的查询,以获取枚举列表并返回值等于列表中任何项的实体?此错误来自Postgres:
错误:运算符不存在:公司类型=字符变化
要解决这个问题,您可以在Postgres中为company_类型创建一个自定义运算符,而不更改代码中的任何内容。像这样:
CREATE FUNCTION ctype_compare(company_type, text)
RETURNS boolean
AS '
select cast($1 as text) = $2;
'
LANGUAGE sql IMMUTABLE;
CREATE OPERATOR = (
leftarg = company_type,
rightarg = text,
procedure = company_type_compare
);
这样,您实际上可以删除@Query,Hibernate将做正确的事情。如果无法创建自定义运算符,可能是因为您没有正确的权限,则必须将查询更改为:
@Query("SELECT c FROM #{#entityName} c " +
"WHERE cast (c.type as text) IN ?1")
然后必须将参数类型固定为字符串
Page<Company> findAllByTypeIn(List<String> types, Pageable pageable);
Page findAllByTypeIn(列表类型,可分页);
要调用DAO方法,请传递正确的类型:
List<String> types = new ArrayList();
types.add(CompanyType.OTHER.toString());
types.add(CompanyType.BUSINESS.toString());
Page<Company> companies = dao.findAllByTypeIn(types, Pageable.unpaged());
List types=new ArrayList();
add(CompanyType.OTHER.toString());
添加(CompanyType.BUSINESS.toString());
Page companys=dao.findAllByTypeIn(类型,Pageable.unpaged());
我是用Java做的,不是Kotlin。但是它应该适合您。将强制转换创建为隐式而不是赋值,这样它也可以用于比较吗
使用INOUT作为隐式创建演员阵容(角色随天数变化)
Page<Company> findAllByTypeIn(List<String> types, Pageable pageable);
List<String> types = new ArrayList();
types.add(CompanyType.OTHER.toString());
types.add(CompanyType.BUSINESS.toString());
Page<Company> companies = dao.findAllByTypeIn(types, Pageable.unpaged());