当前位置: 首页 > 知识库问答 >
问题:

JPA/Hibernate自定义查询和Postgres枚举列表

解晟
2023-03-14

我有一个实体Company,其类型由enumCompanyType表示。数据库是Postgres,在那里表示为枚举类型。我使用JPA/Hibernate及其存储库。请注意,我是JPA、Hibernate和Kotlin的新手。

我试图创建自定义@Query,我需要选择类型(枚举)在可能类型列表中的公司。我,但是,遇到各种错误类型铸造在SQL和/或语法的@Query

Kotlin中数据类公司的主要部分(未复制任何其他属性,包括id):

@Entity(name = "Company")
@Table(name = "company")
data class Company(

    @Enumerated(EnumType.STRING)
    @NotNull
    @Column(name = "type", nullable = false, columnDefinition = "company_type")
    val type: CompanyType = CompanyType.OTHER
) : Serializable

枚举CompanyType的静态编程语言

enum class CompanyType(value: Int) {
    BUSINESS(1),
    TOWN(2),
    NONPROFIT(3),
    RESEARCH(4),
    OTHER(5)
}

在Postgres中枚举company_type

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>
}

但一旦执行,就会发生以下错误:

ERROR: operator does not exist: company_type = character varying

所以我试图铸造它,但不知道具体如何...

    @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: '\'

如何创建这样的查询,以获取枚举列表并返回值等于列表中任何项的实体?


共有2个答案

柳修平
2023-03-14

将强制转换创建为隐式而不是赋值是否有助于将其用于比较?

使用INOUT作为隐式创建演员阵容(角色随天数变化);

太叔繁
2023-03-14

此错误来自Postgres:

错误:运算符不存在:company_type=字符变化

要解决这个问题,您可以在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")

然后必须将参数类型固定为String。

    Page<Company> findAllByTypeIn(List<String> types, Pageable pageable);

要调用DAO方法,需要传递正确的类型:

    List<String> types = new ArrayList();
    types.add(CompanyType.OTHER.toString());
    types.add(CompanyType.BUSINESS.toString());

    Page<Company> companies = dao.findAllByTypeIn(types, Pageable.unpaged());

我是用Java做的,不是Kotlin。但它应该对你有用。

 类似资料:
  • 我需要将枚举列表映射到Postgres中的表。 对于1:1关系的一般映射,我发现这篇文章非常有用。代码如下所示: 但是如果是一个,那么我就可以轻松地找到一个解决方案。因为定义失败了。 为了使其具体化:我有一个表,例如,我可以在其中存储和。为了示例起见,我可以存储多个(例如,基于时间的)。那么如何正确地定义它,如果我有 以同样的方式定义它的方法会导致异常(这似乎很清楚,因为注释是针对而不是针对)

  • enum 关键字允许创建一个代表数个可能变量的数据的类型(原文:The enum keyword allows the creation of a type which may be one of a few different variants.若您对此句有 更好的翻译或理解,希望指出来,谢谢。)。在 struct 中任何合法的变量在 enum 同样是合法的。 // 隐藏未使用代码警告的属性。

  • 我有两个实体: ffice.java 电影JAVA 和以下存储库: 现有的查找方法像左连接一样工作,这正是我需要的。但是如何在不保存电影对象的情况下保存周BoxOffice对象?我真的不知道创建周刊BoxofficeLite的想法。现在它给了一个例外 组织。springframework。刀。InvalidDataAccessApiUsageException:org。冬眠TransientPro

  • 问题内容: 我们有一个带有postgres枚举的postgres数据库。我们开始在应用程序中构建JPA。我们也有Java枚举,它反映了postgres枚举。现在最大的问题是如何让JPA一方面理解Java枚举,另一方面理解Postgres枚举?Java方面应该很容易,但是我不确定如何进行postgres方面。 问题答案: 这涉及进行多个映射。 首先,JDBC驱动程序将Postgres枚举作为PGOb

  • 我有一个班级评语: 保留comment类可以工作,但以下条件查询是有效的: 抛出org.hibernate.exception.DataException:未为参数%1指定值。 这是生成的查询: 选择this_.comment_id作为comment1_0_0_,this_.comment_id作为comment0_0_,commenttop2_.comment_id作为comment1_0_2_

  • 问题内容: 我想要一个Java枚举,其值是整数。 例如: 但是我也想要这两个常量的自定义名称, 例如“ Task Created”和“ Task Deleted”(那里有空格)。 我想尽可能优雅地做到这一点,而无需编写 太多额外的代码。 我可以在没有其他 将枚举常量映射到其自定义名称的映射的情况下实现此目标吗? 我在该项目中使用JDK 6。 问题答案: 只需为此添加一个字段: 如果您不想指定字符串