@Enumerated 映射与 Postgresql 枚举

@Enumerated Mapping with Postgresql Enum

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

我有什么:

Java 部分: 在 java 部分我们定义了 Person.java 实体和 category 枚举 class.

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;

}

CategoryEn.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 
    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;

到这里为止,一切正常,但是当我尝试在 AgentFacade:

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

我遇到以下错误:

Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: org.postgresql.util.PSQLException: ERREUR: operator does not exist : category_enum= character varying

Indication :No operator matches the given name and argument type(s). You might need to add explicit type casts


我的问题是:

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

PS: 我已经看过几乎所有与此主题相似的 Whosebug questions/answers

您收到此错误是因为您的 driver/ORM 可能将该参数转换为 varchar。

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

CREATE OR REPLACE FUNCTION texteq(
    category_enum,
    text)
  RETURNS boolean AS $q$ SELECT texteq(::text, ) $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 中是否真的有效 merges/hashes,但简单的比较看起来不错。