2013-02-25 12 views
10

我正在使用EclipseLink運行一些Native SQL。我需要將數據返回到POJO。我遵循EclipseLink Docs的指示,但我收到錯誤Missing descriptor for [Class]將EclipseLink本機查詢結果導入POJO - [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 

實體Manager呼叫:

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

回答

9

我發現你可以把一個本機查詢執行的結果放到一個保存對象的數組列表中。然後可以迭代列表和數組元素並構建所需的實體對象。

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); 
    } 
5

如果類被映射,你只能使用原生SQL查詢一類。您需要將AnnouncementRecipientsFlattenedDTO類定義爲@Entity。

否則,只需使用SQL創建本機查詢並獲​​取數據的數組,然後使用這些數據自己構建DTO。

+0

是否實體必須與表或相關的就可以了是獨立的嗎? – retrodev 2013-02-26 09:26:10

+0

肯定這是解決問題的答案。以防萬一您想映射到DTO,那麼您可以使用@SqlResultSetMapping – 2016-11-16 09:28:30

8

老問題,但可能是下面的解決方案將幫助別人。

假設您想要返回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; 
} 
+1

這將在數據庫中創建一個名爲TableColumn的新表。其他解決方案? – scarface 2017-01-07 12:59:16

6

另外,別忘了在persistence.xml上添加POJO課程!如果您習慣於爲您管理該文件的IDE,那麼很容易忽略它。

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 Docs here中找到方法調用。

編輯: 事實證明,你必須使用@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註釋的任何地方(所以在這個例子無論是在表A或表B,因爲PojoExample沒有@Entity註解)