【问题标题】:@Enumerated Mapping with Postgresql Enum@Enumerated 与 Postgresql 枚举的映射
【发布时间】:2018-06-09 01:16:38
【问题描述】:

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

我有什么:

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;

}

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 $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;

到这里为止,一切正常,但是当我尝试在AgentFacade 中执行这个query 时:

 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 持久性服务 - 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】:

    您收到此错误是因为您的驱动程序/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 合并/哈希,但简单的比较看起来不错。

    【讨论】:

    • 是的,这很好用,但是请告诉我你知道为什么 JPA 没有一个工具可以自动将 Java 枚举映射到 Sql 类型枚举?
    • 很遗憾,我不知道也没有找到任何关于它的信息。我想部分问题是 MySQL、PostgresSQL 和 MSSQL 之间的 enum 实现不同,根本没有它。
    • 非常感谢 Łukasz
    猜你喜欢
    • 2022-12-14
    • 2015-03-04
    • 2011-07-23
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    • 2011-04-14
    • 2017-03-03
    • 1970-01-01
    相关资源
    最近更新 更多