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 list
和 null
具有不同的语义。
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;
}
}
}
我正在使用 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 list
和 null
具有不同的语义。
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;
}
}
}