2013-02-25 11 views
10

के लिए लापता वर्णनकर्ता मैं कुछ मूल SQL चलाने के लिए EclipseLink का उपयोग कर रहा हूं। मुझे डेटा को पीओजेओ में वापस करने की जरूरत है। मैंने EclipseLink Docs पर निर्देशों का पालन किया, लेकिन मुझे त्रुटि Missing descriptor for [Class]Eclipse मूल क्वेरी परिणाम POJO में जोड़ें - [कक्षा]

क्वेरी कॉलम को 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(); 
} 

उत्तर

9

मुझे पता चला कि आप मूल क्वेरी निष्पादन के परिणामों को ऑब्जेक्ट्स रखने वाली Arrays की सूची में डाल सकते हैं। फिर कोई सूची और ऐरे तत्वों पर पुन: सक्रिय हो सकता है और वांछित इकाई वस्तुओं का निर्माण कर सकता है।

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

आप केवल एक वर्ग के साथ देशी एसक्यूएल प्रश्नों का उपयोग कर सकते हैं अगर वर्ग मैप किया गया है। आपको घोषणाओं को परिभाषित करने की आवश्यकता है FeattenedDTO क्लास को @Entity के रूप में परिभाषित करना होगा।

अन्यथा केवल मूल क्वेरी को केवल SQL के साथ बनाएं और डेटा का सरणी प्राप्त करें और डेटा का उपयोग करके अपने डीटीओ को स्वयं बनाएं।

+0

इकाई एक मेज के साथ जुड़े है की है, हो या कर सकते हैं यह मुक्त खड़े हो जाओ? – retrodev

+0

निश्चित रूप से समस्या को हल करने का उत्तर यही है। बस अगर आप डीटीओ को मैप करना चाहते हैं तो आप उपयोगकर्ता @SqlResultSetMapping –

8

पुराना प्रश्न लेकिन निम्नलिखित समाधान हो सकता है किसी और की मदद करेगा।

मान लीजिए कि आप ओरेकल में किसी दिए गए तालिका के लिए कॉलम, डेटा प्रकार और डेटा लंबाई की एक सूची वापस करना चाहते हैं। मैंने इसके लिए मूल नमूना क्वेरी के नीचे लिखा है:

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 की एक सूची बनाने की आवश्यकता है।

@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 की सूची का निर्माण करने के लिए तैयार हैं:

के रूप में नीचे TableColumn इकाई वर्ग को परिभाषित करें। 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

कर सकते हैं यह तालिका कॉलम नामक डीबी में एक नई तालिका बनाता है। कोई अन्य समाधान? – scarface

6

इसके अलावा, persistence.xml में अपने POJO कक्षा में जोड़ने के लिए मत भूलना! अगर आप अपने आईडीई के लिए उस फाइल को प्रबंधित करते हैं तो इसका उपयोग करना आसान हो सकता है।

2

वही समस्या थी जहां मैं पीओजेओ की सूची वापस करना चाहता था, और वास्तव में केवल पीओजेओ (यदि आप चाहें तो इसे डीटीओ कहते हैं) और @ एंटिटी एनोटेटेड ऑब्जेक्ट्स नहीं।

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 एनोटेशन के तहत कहीं भी इस डाल (इस उदाहरण या तो TableA या tableb में में इसलिए है क्योंकि PojoExample कोई @Entity एनोटेशन है)

संबंधित मुद्दे