EclipseLink:PostgreSQL 返回空列表作为文本 [] 的默认值?

EclipseLink: PostgreSQL returning empty list as defualt value for text[]?

我正在使用 postgresql 作为我的数据库并且在应用程序服务器 (AS) 端使用 Java 使用 JPA(Java 持久性 API)实现 eclipselink.

我在 postgres 中使用 text[] 作为数据类型的某些列映射到 AS 端的 jpa 对象中的 List

JPA

    @Struct(name="label,.....")
    @Entity
    @Table(name="\"XYZ\"", schema="\"XYZ\"")
    @NamedQuery(name="XYZ.findAll", query="SELECT r FROM XYZ r")
    public class XYZ implements  Serializable {
        private static final long serialVersionUID = 1L;

        @Id
        @Column(name="\"resourceID\"")
        private String resourceID;

        @Array(databaseType = "text")
        @Column(name="\"label\"")
        private List<String> label;

.........
        // getter/setters 

}

所以在这里,label 在 postgres 中存储为 text[] 并映射到 JPA 对象中的 List<String>

当我将具有 List 值的 JPA 对象保存为 null 时,在检索 JPA 时我得到 Empty list 作为值,但从来没有 .

为什么 Postgres 返回 empty list 作为默认值,即使我在保存时将其设置为 null。对于我的用例,empty listnull 具有不同的语义。

String 类型不会发生,它不会给出空字符串。

是否text[]默认为空列表?

我找不到关于这个问题的任何具体信息??

**编辑 1:** 我尝试在 JPA 中将字段设置为 String[],如下所示:

    @Struct(name="label,.....")
    @Entity
    @Table(name="\"XYZ\"", schema="\"XYZ\"")
    @NamedQuery(name="XYZ.findAll", query="SELECT r FROM XYZ r")
    public class XYZ implements  Serializable {
        private static final long serialVersionUID = 1L;

        @Id
        @Column(name="\"resourceID\"")
        private String resourceID;


        @Column(name="\"label\"")
        private String[] label;

.........
        // getter/setters 

}

我在运行时遇到异常:

堆栈跟踪:

Caused by: org.postgresql.util.PSQLException: ERROR: column "label" is of type text[] but expression is of type bytea
  Hint: You will need to rewrite or cast the expression.
  Position: 413
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2182)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1911)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:173)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:615)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:465)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:411)
    at org.jboss.jca.adapters.jdbc.CachedPreparedStatement.executeUpdate(CachedPreparedStatement.java:119)
    at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeUpdate(WrappedPreparedStatement.java:493)

编辑 2:

在尝试您的回答中提到的 ListToArrayConverter 时,我在坚持时遇到异常:

Internal Exception: org.postgresql.util.PSQLException: ERROR: column "label" is of type text[] but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.

EclipseLink 处理 List 就像处理 ToMany 关系一样,因此它总是用空 List 初始化。源代码可以在这里找到:https://github.com/eclipse-ee4j/eclipselink

如果您不喜欢空列表而想要空列表,您可以创建自己的转换器,例如:

@Converter(autoApply = true)
public class ListToArrayConveter implements AttributeConverter<List<String>, Object> {

    @Override
    public PostgreSQLTextArray convertToDatabaseColumn(List<String> attribute) {
        if (attribute == null || attribute.isEmpty()) {
            return null;
        }
        String[] rst = new String[attribute.size()];
        return new PostgreSQLTextArray(attribute.toArray(rst));
    }

    @Override
    public List<String> convertToEntityAttribute(Object dbData) {
            List<String> rst = new ArrayList<>();
        String[] elements = ((String[]) dbData);
        for (String element : elements) {
            rst.add(element);
        }
        if (list.isEmpty()) {
            return null;
        } else {
            return rst;
        }
    }
}