JPA 2(EclipseLink)尝试使用UUID作为主键,但是EntityManager.find()总是抛出异常(数据库是PostgreSQL)

5

我正在尝试使用JPA 2(EclipseLink)将UUID用作主键。我正在使用PostgreSQL作为数据库。我的实体声明如下:我有一个Employee表,其PK设置为UUID。我有一个JPA实体映射到员工表,如下所示:

@Entity
public class Employee {
    @Id
    private String id;
    ...
    ...
}

当我调用EntityManager.find(Employee.class, id)时,我从postgres得到了一个异常:
内部异常:org.postgresql.util.PSQLException: ERROR: operator does not exist: uuid = character varying
提示:没有匹配给定名称和参数类型的运算符。您可能需要添加显式类型转换。
我还尝试将Employee类中的id更改为java.util.UUID,但是然后我会得到以下(非常相似的)错误:
内部异常:org.postgresql.util.PSQLException: ERROR: operator does not exist: uuid = bytea 提示:没有匹配给定名称和参数类型的运算符。您可能需要添加显式类型转换。
我真的不知道该如何解决这个问题...有人有什么想法吗?
谢谢!
2个回答

3
我正在尝试使用JPA 2(EclipseLink)将UUID用作主键。不幸的是,标准的JPA没有将UUID作为生成标识符的策略。
我也尝试将Employee类中的id更改为java.util.UUID(...)。但这不是Id的有效类型(在您的情况下已被视为Serializable)。JPA 2.0规范指出:

2.4 主键和实体标识

...

一个简单的主键或复合主键的字段或属性应该是以下类型之一: 任何Java原始类型;任何原始包装类型; java.lang.Stringjava.util.Datejava.sql.Datejava.math.BigDecimaljava.math.BigInteger。如果主键是从另一个实体的主键派生的复合主键,则主键可以包含一个属性,其类型是所述部分 2.4.1 中描述的引用实体的主键的类型。使用其他类型作为主键的实体将不具有可移植性。 如果使用生成的主键,则仅整数类型将具有可移植性。如果将 java.util.Date 用作主键字段或属性,则应将时间类型指定为 DATE

换句话说,如果有解决方案,它将是特定于提供程序的。

我真的不确定该如何解决这个问题... 有人有什么想法吗?

您需要为自定义排序配置EL,并提供自定义序列生成器。请参见EclipseLink/Examples/JPA/CustomSequencing获取完整示例(使用UUID生成器)。


你该如何查询实体呢?我尝试了很多不同的本地 SQL 查询和 JPQL 查询,但无法让它正常工作。如果我直接针对数据库进行查询,它看起来像这样:SELECT * FROM employee where id = 'my-uuid-here',并且可以正常工作... 你认为在 JPA 中再现这个查询很容易吗? - Brian DiCasa
@Brian 你在JPQL中尝试了什么? - Pascal Thivent
你所链接的自定义序列生成器是否具有可移植性? - Theo

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接