2013-11-27 103 views
0

我有一个遗留的表有很多列,我试图限制休眠的列数。如果我只是从“from”子句运行到最后,它可以正常工作,加载每一列,但是当我添加“Select a.col1,a.col2 ...”等时,我得到一个对象数组而不是bean的实例。休眠选择子句不起作用

我尝试添加一个结果变压器,但它似乎认为第一列被命名为“0”。我猜想在结果转换器进入画面时已经损坏了。我想知道,如果可能有一个案件不匹配,所以我把所有东西都变成了大写,但这并没有帮助。

UPDATE: 这里的SQL:

Select a.SZ_ABND_NO, a.ASSET_VAL, a.FO_TYP, a.ASSET_ID, a.AGCY_RGN_CD, a.LIT_AGCY_CD, a.ASSET_TYP, a.SZ_AGCY_CD, a.SUB_OFC_ID, a.OFC_ID, a.CA_ID_AGCY, a.PROC_DIST from FlatAssetT a where a.ASSET_ID in (:assetList) order by a.ASSET_ID 

的bean是巨大的。这12列是数百(是复数)。我会给出一个选定的代码片段。

@Entity 
@Table(name = "FLATASSET_T", schema="K702PRDR") 
public class FlatAssetT { 
    @Column(name="ADPT_DT", nullable=false) 
    private Date ADPT_DT; 

    @Id 
    @Column(name="ASSET_ID", nullable=false) 
    private String ASSET_ID; 

    @Column(name="ASSET_ID_TYP", nullable=false) 
    private String ASSET_ID_TYP; 

    @Column(name="SZ_ABND_NO", nullable=false) 
    private String SZ_ABND_NO; 
[etc.] 
    public String getSZ_ABND_NO() { 
     return SZ_ABND_NO; 
    } 
    public void setSZ_ABND_NO(String arg) { 
     this.SZ_ABND_NO=arg; 
    } 
    public String getASSET_ID() { 
     return ASSET_ID; 
    } 
    public void setASSET_ID(String arg) { 
     this.ASSET_ID=arg; 
    } 
    public Date getADPT_DT() { 
     return ADPT_DT; 
    } 
    public void setADPT_DT(Date arg) { 
     this.ADPT_DT=arg; 
    } 
    public String getASSET_ID_TYP() { 
     return ASSET_ID_TYP; 
    } 
    public void setASSET_ID_TYP(String arg) { 
     this.ASSET_ID_TYP=arg; 
    } 
[etc.] 
} 
+0

你可以帮助我们发布你想要选择的bean吗?也许当前表的SQL创建?此外,不要忘记提及,如果你使用纯粹的JPA或Hibernate API,它是HQL还是JPQL?使用hibernate标准API?它帮助我们尝试和调试问题:) –

+0

@André - 使用HQL。该表不是由休眠创建的。它是一个遗留表格。用字符串用户输入密钥(asset_id)非常简单。除了它存在以外,我对标准API一无所知。我听说“预测”在这里很有帮助,但我不知道如何。 – user1187719

回答

0

除了bean的默认构造函数有一个走的是一套有限的参数(匹配那些你是从数据库获取),然后使用“选择新为myBean(..)的自定义构造函数。 ..' 句法。请参阅下面的链接以获取更详细的解释。

New object with HQL

你也可以给别名每一列您选择,然后填充图所示

http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-select

select new map(max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n) 
from Cat cat 

可能是你可以介绍一个构造函数来你的bean接受地图,然后使用这个(加盟两种方式)

+0

听起来很整齐!但不幸的是,我想部分选择是动态的。采用列返回列表的单个dao方法。这部分是因为这是一个Web服务的一部分,我打算接受他们想要返回的信息列表。 – user1187719

+0

我忘了把at放在前面的评论中,所以我加了一秒,希望能够通知你。 – user1187719

0

您可以使用此我进行查询从的ThOD这article

它使用了Apache的BeanUtils。作者将参数的实现留给读者作为“作业”。

在本质上,查询数据并遍历结果创建新的bean实例和可用的数据设置为它创建与豆新的列表。

public List find(final String hqlQuery) throws Exception { 

    List results = new ArrayList(); 
    Query query = SessionManager.currentSession().createQuery(hqlQuery); 
    Type beanType = query.getReturnTypes()[0]; 
    Class beanClass = beanType.getReturnedClass(); 
    String[] columns = extractColumns(hqlQuery); 
    String[] attributeNames = getAttributeFieldNames(columns); 
    String[] resultFieldNames = getResultFieldNames(columns); 
    Iterator iter = query.iterate(); 
    while(iter.hasNext()) { 
     Object[] row = (Object[]) iter.next(); 
     Object bean = beanClass.newInstance(); 
     for (int j = 0; j < row.length; j++) { 
      if (row[j] != null) { 
       initialisePath(bean, attributeNames[j]); 
       PropertyUtils.setProperty(bean, attributeNames[j], row[j]); 
      } 
     } 
     results.add(bean); 
    } 
    return results; 
    } 

    private static void initialisePath(final Object bean, final String fieldName) throws Exception { 
      int dot = fieldName.indexOf('.'); 
      while (dot >= 0) { 
       String attributeName = fieldName.substring(0, dot); 
       Class attributeClass = PropertyUtils.getPropertyType(bean, attributeName); 
       if (PropertyUtils.getProperty(bean, attributeName) == null) { 
        PropertyUtils.setProperty(bean, attributeName, attributeClass.newInstance()); 
      } 
      dot = fieldName.indexOf('.', dot + 1); 
      } 
    }