@Enumerated映射与Postgresql枚举

时间:2017-12-28 13:26:09

标签: postgresql jpa enums orm jpql

我创建了一个名为entity的简单Agent,其中包含枚举category。我已经知道JPA不会将此enum Postgresql 类型enum进行映射,因此我尝试强制此映射。

我有什么:

我们已经定义了Person.java实体和category枚举类的java部分中的

Java部件:

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;

在此之前,一切正常,但当我尝试在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的工具?
  4. PS :我已经看到几乎所有与此主题类似的stackoverflow问题/答案

1 个答案:

答案 0 :(得分: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合并/哈希中有效,但简单的比较看起来很好。