Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EclipseLink native query result into POJO - Missing descriptor for [Class]

I'm using EclipseLink to run some Native SQL. I need to return the data into a POJO. I followed the instructions at EclipseLink Docs, but I receive the error Missing descriptor for [Class]

The query columns have been named to match the member variables of the POJO. Do I need to do some additional mapping?

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

Entity Manager call:

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();
}
like image 554
retrodev Avatar asked Feb 25 '13 16:02

retrodev


3 Answers

I found out you can put the results of a Native Query execution into a List of Arrays that hold Objects. Then one can iterate over the list and Array elements and build the desired Entity objects.

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);
    }
like image 117
retrodev Avatar answered Oct 15 '22 07:10

retrodev


You can only use native SQL queries with a class if the class is mapped. You need to define the AnnouncementRecipientsFlattenedDTO class as an @Entity.

Otherwise just create the native query with only the SQL and get an array of the data back and construct your DTO yourself using the data.

like image 35
James Avatar answered Oct 15 '22 06:10

James


Old question but may be following solution will help someone else.

Suppose you want to return a list of columns, data type and data length for a given table in Oracle. I have written below a native sample query for this:

  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";

Now the requirement is to construct a list of POJO from the result of above query.

Define TableColumn entity class as below:

@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();
}

}

Now we are ready to construct a list of POJO. Use the sample code below to construct get your result as List of POJOs.

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;
}
like image 34
A J Qarshi Avatar answered Oct 15 '22 08:10

A J Qarshi