2017-05-05 71 views
0

我運行下面的語句問題與JPA 2.0 EnityManger.createNativeQuery

List<TableA> tableAList = (List<TableA>) entityManager. 
          createNativeQuery(
          "select colA, colB from tableA", 
          TableA.class) 
          .getResultList(); 

TableA的實體

@Enitity 
@Column(name = "tableA") 
public class TableA { 
    @Id 
    private Integer id; 

    @Column(name = "colA") 
    private Integer colA; 

    @Column(name = "colB") 
    private Integer colB; 

    @Column(name = "colC") 
    private Integer colC; 

    @Column(name = "colD") 
    private Integer colD; 

    /* 
    Corresponding getters and setters. Excluding them for brevity. 
    */ 
} 

上面的查詢拋出的SQLException說: 「COLC」 沒有找到。如果我在選擇列表中添加colC,它會顯示找不到「colD」。本質上,它希望表中的所有列都包含在select查詢中。如果我不添加resultClass,只是得到的響應爲List<Object[]>,則不會發生同樣的錯誤。任何人都可以解釋爲什麼發生這種行爲?

有沒有辦法以List的形式獲取響應,將剩餘的字段設置爲null(或者如果有任何原始字段,則爲默認基元)?

堆棧跟蹤:

java.sql.SQLException: Column 'colC' not found. 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:963) 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:896) 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:885) 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860) 
    at com.mysql.jdbc.ResultSetImpl.findColumn(ResultSetImpl.java:1077) 
    at com.mysql.jdbc.ResultSetImpl.getLong(ResultSetImpl.java:2759) 
    at org.hibernate.type.descriptor.sql.BigIntTypeDescriptor$2.doExtract(BigIntTypeDescriptor.java:63) 
    at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47) 
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:260) 
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:256) 
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:246) 
    at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:332) 
    at org.hibernate.loader.Loader.extractKeysFromResultSet(Loader.java:802) 
    at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:727) 
    at org.hibernate.loader.Loader.processResultSet(Loader.java:985) 
    at org.hibernate.loader.Loader.doQuery(Loader.java:943) 
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349) 
    at org.hibernate.loader.Loader.doList(Loader.java:2615) 
    at org.hibernate.loader.Loader.doList(Loader.java:2598) 
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2430) 
    at org.hibernate.loader.Loader.list(Loader.java:2425) 
    at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:335) 
    at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:2153) 
    at org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:991) 
    at org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:147) 
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1410) 
    at org.hibernate.query.Query.getResultList(Query.java:146) 

注:我使用JPA 2.0。

+0

爲什麼不直接用數據庫中實際選擇的字段來定義實體? 如果您告訴JPA結果是某個類,它將確保從結果集中提取所有屬性。結果集中的值可能爲空,但結果集內的列必須存在。 – Matthias

+0

如果選擇組合是靜態的,我會創建一個實體。我正在使用查詢生成器,我們可以選擇任何列的組合。有沒有其他辦法讓我選擇列動態? – yaswanth

+0

如果選擇動態數量的列,那麼將其映射到實體是一件很奇怪的事情;當然你可以重寫你的SQL查詢來選擇其他列作爲空值。也就是說,您不希望從表中檢索到的每一列,在查詢中包含「null AS 」。這是在你的情況上面「選擇a.colA作爲colA,a.colB作爲colB,null作爲colC,null作爲colD從tableA a」 – Matthias

回答

1

如果您未指定resultClass,則JPA無法知道給出的結果類型,因此它會返回所有列值的數組。每個Object[]是一個返回的行。

如果您不想獲取colC和colD,但仍然使用結果類,則必須在其相應的名稱和數據類型中輸入假字段。

List<TableA> tableAList = (List<TableA>) entityManager.createNativeQuery(
        "select colA, colB, null as colC, null as colD from tableA", 
        TableA.class).getResultList(); 

如果您的字段碰巧是原始的,則使用0而不是null。

+0

有沒有配置或ResultHandler類的東西,這對我來說?因爲我不想在每個查詢中包含虛擬空值和默認的原始值。 – yaswanth

+0

不可以。但是,您可以創建一個不同的更小的實體類來使用它。 – coladict

+0

我不能那樣做。我的實體類通常包含多達15個字段,我可以選擇它們的任意組合。 – yaswanth