java - 使用 Spring Data JDBC 在 Postgresql 中映射 Java 枚举

标签 java postgresql enums spring-data-jdbc

我希望能够将在 java 中声明的枚举映射到在 postgres 中创建的枚举。例如具有以下内容:

CREATE TYPE EYE_COLOR AS ENUM ('BROWN', 'BLUE', 'GREEN');
CREATE TABLE PERSON (
    ID       INT PRIMARY KEY AUTO_INCREMENT,
    NAME     NVARCHAR2(128) NOT NULL,
    EYE      EYE_COLOR
);

在java中我有这样的东西:

public enum EyeColor {
    BROWN,
    BLUE,
    GREEN
}
public class Person {
    @Id
    Long id;
    String name;
    EyeColor eye;
}

当我尝试像这样将某些内容保存到数据库时:

personRepository.save(new Person("test", EyeColor.BROWN))

sql 日志似乎没问题:

Executing prepared SQL statement [INSERT INTO person (name, eye) VALUES (?, ?)]
 o.s.jdbc.core.StatementCreatorUtils      : Setting SQL statement parameter value: column index 1, parameter value [test], value class [java.lang.String], SQL type 12
 o.s.jdbc.core.StatementCreatorUtils      : Setting SQL statement parameter value: column index 2, parameter value [BROWN], value class [java.lang.String], SQL type 12

但在实际的数据库字段中我得到一个异常文本:

org.h2.jdbc.JdbcSQLException: General error: "java.lang.RuntimeException: type=25" [50000-196]  
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)     
at org.h2.message.DbException.get(DbException.java:168)     
at org.h2.message.DbException.convert(DbException.java:295)     
at org.h2.message.DbException.toSQLException(DbException.java:268)  
at org.h2.message.TraceObject.logAndConvert(TraceObject.java:352)   
at org.h2.jdbc.JdbcResultSetMetaData.getColumnClassName(JdbcResultSetMetaData.java:376)     
at com.intellij.database.remote.jdbc.impl.RemoteResultSetImpl.getObject(RemoteResultSetImpl.java:1269)  
at com.intellij.database.remote.jdbc.impl.RemoteResultSetImpl.getCurrentRow(RemoteResultSetImpl.java:1249)  
at com.intellij.database.remote.jdbc.impl.RemoteResultSetImpl.getObjects(RemoteResultSetImpl.java:1229)     
at sun.reflect.GeneratedMethodAccessor13.invoke(Unknown Source)     
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)    
at java.lang.reflect.Method.invoke(Method.java:498)     
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:346)  
at sun.rmi.transport.Transport$1.run(Transport.java:200)    
at sun.rmi.transport.Transport$1.run(Transport.java:197)    
at java.security.AccessController.doPrivileged(Native Method)   
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)  
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)     
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)     
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)     
at java.security.AccessController.doPrivileged(Native Method)   
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)  
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)  
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)  
at java.lang.Thread.run(Thread.java:745) Caused by: java.lang.RuntimeException: type=25

如果我将 postgres 列定义中的 EYE_COLOR 类型替换为 NVARCHAR2(128),一切正常。插入了实际的“BROWN”值。

关于如何实现的任何想法?

LE:忘记添加我的 spring 数据库驱动程序:

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:file:path/to/file;DB_CLOSE_DELAY=-1;MODE=PostgreSQL;AUTO_SERVER=TRUE

我也尝试使用 ENUM 定义,就像他们在列定义中直接在 H2 驱动程序规范中所说的那样,但仍然没有用:

CREATE TABLE PERSON (
     ID       INT PRIMARY KEY AUTO_INCREMENT,
     NAME     NVARCHAR2(128) NOT NULL,
     EYE      ENUM ('BROWN', 'BLUE', 'GREEN')
);

最佳答案

目前在 Spring Data JDBC 中没有对 Postgres 枚举的特殊支持。

但如此处所述:https://stackoverflow.com/a/40356977/66686 Postgres 枚举需要一些特殊的 SQL 语法才能被操作。

这允许以下可能的问题解决方案:

  1. 在数据库中使用 VARCHAR 而不是 ENUM
  2. 使用 @Query 注释方法,使用枚举的特殊语法。这仅在您的聚合仅包含单个实体时才可行。

关于java - 使用 Spring Data JDBC 在 Postgresql 中映射 Java 枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53190112/

相关文章:

java - 使用 Spring 3.1.3 时 EclipseLink 2.4.1 抛出的 TransactionRequiredException

java - 为什么实现 Serializable 的对象的序列化会抛出异常?

sql - postgresql 中的 NOT IN 子句

postgresql - 列 "expired_date"是日期类型,但表达式是文本类型

postgresql - 在 PostgreSQL 中更改系统语言和错误消息

Java NoClassDefFoundError

java - Maven 项目在 prod 中寻找不存在的路径

c# - InvalidCastException 尝试从装箱的 int 转换为可为 null 的枚举

jsf - 从 Map 访问值,其中 Key 是 JSF Facelets 中的枚举类型

postgresql - 如何创建作为一组枚举值的 PostgreSQL 列?