@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
我的问题是:
- 为什么我会遇到这个错误?
- 我可以解决这个错误吗?怎么样?
- 为什么
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,但简单的比较看起来不错。
我创建了一个名为 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
我的问题是:
- 为什么我会遇到这个错误?
- 我可以解决这个错误吗?怎么样?
- 为什么
JPA
没有自动将 Javaenum
映射到 Sqltype 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,但简单的比较看起来不错。