我将postgresql
用作数据库,并通过JPA(Java持久性API)实现eclipselink
在应用程序服务器(AS)端使用Java。
在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 作为值,但从来没有 null 空> strong>。
即使我保存时,为什么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
}
运行时出现异常:
Stacktrace:
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.
答案 0 :(得分:1)
EclipseLink就像处理ToMany关系一样处理List,因此始终使用空List对其进行初始化。可以在这里找到源代码:https://github.com/eclipse-ee4j/eclipselink
如果您不喜欢空白列表,而是想要null,则可以创建自己的转换器,例如:
@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;
}
}
}