@Enumerated映射与Postgresql枚举

问题描述 投票:0回答:1

我创建了一个简单的entity,名为Agent,有一个枚举的category。我已经知道JPA不会将这个enum映射到Postgresql类型enum所以我试图强制这个映射。

What I Have:

Java部分:在java部分中,我们定义了Person.java实体和category枚举类。

person.Java

@Entity
public class Agentimplements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;


    @Column(length = 50, nullable = false)
    private String code;
    @Column(length = 50, nullable = false)
    private String first_name;
    @Column(length = 50, nullable = false)
    private String family_name;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private TypeEntree category;

}

category en.Java

public enum CategoryEn{
    CUSTOMER,
    PROVIDER,
    DRIVER
}

Sql强制:

CREATE TYPE category_enum AS ENUM ('CUSTOMER','PROVIDER','DRIVER');

CREATE FUNCTION dummy_cast(varchar) RETURNS category_enum AS $$
SELECT CASE $1
    WHEN 'CUSTOMER' THEN 'CUSTOMER'::category_enum
    WHEN 'PROVIDER' THEN 'PROVIDER'::category_enum
    WHEN 'DRIVER' THEN 'DRIVER'::category_enum
END;
$$ LANGUAGE SQL;

CREATE CAST (varchar AS category_enum) WITH FUNCTION dummy_cast(varchar) AS ASSIGNMENT;

ALTER TABLE public.agent
ALTER COLUMN category
SET DATA TYPE category_enum
USING agent::text::category_enum;

直到这里,一切都工作正常,但当我尝试在query执行这个AgentFacade时:

 String jpql ="SELECT a FROM Agent a"
                + " WHERE a.category = :cat";
        Query query = em.createQuery(jpql);
        query.setParameter("cat", CategoryEn.DRIVER);

我有以下错误:

引发者:javax.persistence.PersistenceException:异常[EclipseLink-4002](Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd):org.eclipse.persistence.exceptions.DatabaseException内部异常:org.postgresql.util.PSQLException:ERREUR :运算符不存在:category_enum =字符变化

指示:没有运算符匹配给定的名称和参数类型。您可能需要添加显式类型转换


我的问题是:

  1. 为什么我有这个错误?
  2. 我能解决这个错误吗?怎么样?
  3. 为什么JPA没有自动将Java enum映射到Sql type enum的工具?

PS:我已经看到几乎所有与本主题类似的stackoverflow问题/答案

postgresql jpa enums orm jpql
1个回答
1
投票

您收到此错误是因为您的驱动程序/ ORM可能会将该参数强制转换为varchar。

您可以为该比较创建运算符:

CREATE OR REPLACE FUNCTION texteq(
    category_enum,
    text)
  RETURNS boolean AS $q$ SELECT texteq($1::text, $2) $q$
  LANGUAGE SQL IMMUTABLE STRICT
  COST 1;

CREATE OPERATOR =(
  PROCEDURE = texteq,
  LEFTARG = category_enum,
  RIGHTARG = text,
  COMMUTATOR = =,
  NEGATOR = <>,
  RESTRICT = eqsel,
  JOIN = eqjoinsel,
  HASHES,
  MERGES);

我没有测试它是否实际上在JOIN合并/哈希中有效,但简单的比较看起来很好。

© www.soinside.com 2019 - 2024. All rights reserved.