如何将Postgresql ARRAY_AGG数据转换为Java Set

时间:2018-07-02 18:36:35

标签: java sql postgresql hibernate jpa

我试图在本机SQL查询中获取一些数据为ARRAY_AGG():

ARRAY_AGG(table.foo) as foos

(查询中有GROUP BY,因此必须为ARRAY_AGG才能将结果转换为单个数组类型的列值。)

它需要转换为Java集:

Set<Long> foos;

在我的POJO课堂上。

如果有另一种方法,则不必使用ARRAY_AGG。

现在,我在打电话时遇到了异常:

this.entityManager.createNativeQuery(sql).getResultList();
javax.persistence.PersistenceException: org.hibernate.MappingException: No Dialect mapping for JDBC type: 2003
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
    at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:458)

有什么方法可以避免该异常并转换数据?

1 个答案:

答案 0 :(得分:0)

好吧,由于您使用的是旧版本,因此可能的解决方案是使用自定义解析器和这些注释。

@Transient
private Set<String> aggs;

@Column(name = "the_agg_column")
private String raw;

@PostLoad
protected void readAgg() {
Set<String> s = new TreeSet<>();
StringBuilder sb = new StringBuilder();
boolean isquoted = false;
final int len = raw.length();
for (int i = 0; i < len; i++) {

    char c = raw.charAt(i);
    if (c == '"') {
        if (sb.length() == 0) isquoted = true;
        else if (isquoted) isquoted = false;
        continue;
    }
    if (c == ',' || c == '}') {
          // do finish-up
          s.add(sb.toString());
          sb.setLength(0);
          continue;
    }
    if (isquoted && c == '\\') {
        c = raw.charAt(++i);
    }
    sb.append(c);
}

这基本上告诉Hibernate您想要以String格式获取它,因此您必须解析Postgres数组字符串格式。

转义字符处理可能与某些特殊情况有关,但是我敢打赌,您使用的是Enum,这就是为什么我使用Set(或者最好是EnumSet)的原因。

如果您确实希望可能需要转义"\以外的字符,这将为您https://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-BACKSLASH-TABLE

提供帮助