17

我正在使用 EclipseLink 运行一些本机 SQL。我需要将数据返回到 POJO。我按照EclipseLink Docs上的说明进行操作,但收到错误消息Missing descriptor for [Class]

已命名查询列以匹配 POJO 的成员变量。我需要做一些额外的映射吗?

POJO:

public class AnnouncementRecipientsFlattenedDTO {

        private BigDecimal announcementId;
        private String recipientAddress;
        private String type;

        public AnnouncementRecipientsFlattenedDTO() {
            super();
        }

        public AnnouncementRecipientsFlattenedDTO(BigDecimal announcementId, String recipientAddress, String type) {
            super();
            this.announcementId = announcementId;
            this.recipientAddress = recipientAddress;
            this.type = type;
        }

    ... Getters/Setters

实体管理器调用:

public List<AnnouncementRecipientsFlattenedDTO> getNormalizedRecipientsForAnnouncement(int announcementId) {
    Query query = em.createNamedQuery(AnnouncementDeliveryLog.FIND_NORMALIZED_RECIPIENTS_FOR_ANNOUNCEMENT, AnnouncementRecipientsFlattenedDTO.class);
    query.setParameter(1, announcementId);
    return query.getResultList();
}
4

5 回答 5

11

我发现您可以将本机查询执行的结果放入包含对象的数组列表中。然后可以遍历列表和数组元素并构建所需的实体对象。

List<Object[]> rawResultList;

    Query query =
        em.createNamedQuery(AnnouncementDeliveryLog.FIND_NORMALIZED_RECIPIENTS_FOR_ANNOUNCEMENT);
    rawResultList = query.getResultList();

    for (Object[] resultElement : rawResultList) {
        AnnouncementDeliveryLog adl = new AnnouncementDeliveryLog(getAnnouncementById(announcementId), (String)resultElement[1], (String)resultElement[2], "TO_SEND");
        persistAnnouncementDeliveryLog(adl);
    }
于 2013-03-11T14:33:33.410 回答
9

如果类已映射,则只能对类使用本机 SQL 查询。您需要将 AnnouncementRecipientsFlattenedDTO 类定义为 @Entity。

否则,只需使用 SQL 创建本机查询并获​​取数据数组并使用数据自己构建 DTO。

于 2013-02-25T16:36:02.050 回答
9

老问题,但可能会遵循解决方案将帮助其他人。

假设您要返回 Oracle 中给定表的列、数据类型和数据长度的列表。我在下面写了一个本机示例查询:

  private static final String TABLE_COLUMNS = "select utc.COLUMN_NAME, utc.DATA_TYPE, utc.DATA_LENGTH "
        + "from user_tab_columns utc "
        + "where utc.table_name = ? "                
        + "order by utc.column_name asc";

现在的要求是根据上述查询的结果构造一个 POJO 列表。

定义TableColumn实体类如下:

@Entity
public class TableColumn implements Serializable {

@Id
@Column(name = "COLUMN_NAME")
private String columnName;
@Column(name = "DATA_TYPE")
private String dataType;
@Column(name = "DATA_LENGTH")
private int dataLength;

public String getColumnName() {
    return columnName;
}

public void setColumnName(String columnName) {
    this.columnName = columnName;
}

public String getDataType() {
    return dataType;
}

public void setDataType(String dataType) {
    this.dataType = dataType;
}

public int getDataLength() {
    return dataLength;
}

public void setDataLength(int dataLength) {
    this.dataLength = dataLength;
}

public TableColumn(String columnName, String dataType, int dataLength) {
    this.columnName = columnName;
    this.dataType = dataType;
    this.dataLength = dataLength;
}

public TableColumn(String columnName) {
    this.columnName = columnName;
}

public TableColumn() {
}

@Override
public int hashCode() {
    int hash = 0;
    hash += (columnName != null ? columnName.hashCode() : 0);
    return hash;
}

@Override
public boolean equals(Object object) {

    if (!(object instanceof TableColumn)) {
        return false;
    }
    TableColumn other = (TableColumn) object;
    if ((this.columnName == null && other.columnName != null) || (this.columnName != null && !this.columnName.equals(other.columnName))) {
        return false;
    }
    return true;
}

@Override
public String toString() {
    return getColumnName();
}

}

现在我们准备构建一个 POJO 列表。使用下面的示例代码将结果构建为 POJO 列表。

public List<TableColumn> findTableColumns(String table) {
    List<TableColumn> listTables = new ArrayList<>();
    EntityManager em = emf.createEntityManager();
    Query q = em.createNativeQuery(TABLE_COLUMNS, TableColumn.class).setParameter(1, table);
    listTables = q.getResultList();
    em.close();
    return listTables;
}
于 2013-10-31T17:00:19.103 回答
9

另外,不要忘记在您的 POJO 类中添加persistence.xml!如果您习惯于 IDE 为您管理该文件,这很容易被忽略。

于 2014-03-07T20:23:53.807 回答
2

有同样的问题,我想返回一个 POJO 列表,实际上只是 POJO(如果你愿意,可以称之为 DTO)而不是 @Entity 注释对象。

class PojoExample {

  String name;

  @Enumerated(EnumType.STRING)
  SomeEnum type;

  public PojoExample(String name, SomeEnum type) {
    this.name = name;
    this.type = type;
  }
}

使用以下查询:

String query = "SELECT b.name, a.newtype as type FROM tablea a, tableb b where a.tableb_id = b_id";

Query query = getEntityManager().createNativeQuery(query, "PojoExample");

@SuppressWarnings("unchecked")
List<PojoExample> data = query.getResultList();

从数据库创建 PojoExample,而不需要 PojoExample 上的实体注释。您可以在此处的 Oracle 文档中找到方法调用。

编辑:事实证明,您必须使用 @SqlResultSetMapping 才能使其工作,否则您的 query.getResultList() 将返回对象列表。

@SqlResultSetMapping(name = "PojoExample", 
  classes = @ConstructorResult(columns = {
    @ColumnResult(name = "name", type = String.class), 
    @ColumnResult(name = "type", type = String.class)
  }, 
  targetClass = PojoExample.class)
 )

只需将其放在 @Entity 注释下的任何位置(因此在此示例中,在 tablea 或 tableb 中,因为 PojoExample 没有 @Entity 注释)

于 2017-08-30T08:38:45.727 回答