【问题标题】:How to query a database table for a list of record with only two data objects如何在数据库表中查询只有两个数据对象的记录列表
【发布时间】:2014-10-19 10:12:46
【问题描述】:

我的数据库表如下:

ID      ACCESSID    ENTITYGUID      NAME    NAMEID      OWNERGUID   TIMECREATED     VALUEID     VALUETYPE  

我只想检索包含两个字段的列表,namevalueId,而不是整个记录。我正在尝试如下:

通过预测:

public void getAllEntityMetadata(int GUID) {
        Criteria c = session.createCriteria(RevMetadata.class)
                .add(Restrictions.eq("entityGUID", GUID))
                .setProjection(Projections.property("name"))
                .setProjection(Projections.property("nameId"));

        List<RevMetadata> m = (List<RevMetadata>) (RevMetadata) c.list();
        for (RevMetadata item : m) {
            System.out.println("-> All entity metadata for GUID: " + item.getName() + " : " + item.getValueId());
        }
}

我得到错误:

Caused by: java.lang.ClassCastException: java.util.ArrayList cannot be cast to wakiliproject.Persistence.RevMetadata
    at wakiliproject.Persistence.PersistRevMetadata.getAllEntityMetadata(PersistRevMetadata.java:112)
    at wakiliproject.HomeController.showMetastring(HomeController.java:492)
    ... 40 more

通过示例查询,我只得到下面的输出,但没有数据。没有错误被调用:

public void getAllEntityMetadataEg(int GUID) {
        RevMetadata m = new RevMetadata();
        m.setEntityGUID(GUID);
        Example e = Example.create(m);

        Criteria c = session.createCriteria(RevMetadata.class).add(e);
        for (Iterator it = c.list().iterator(); it.hasNext();) {
            RevMetadata item = (RevMetadata) it.next();
            System.out.println("-> All entity metadata for GUID: " + item.getName() + " : " + item.getValueId());
        }
}

输出:

Hibernate: select this_.id as id1_4_0_, this_.accessId as accessId2_4_0_, this_.entityGUID as entityGU3_4_0_, this_.name as name4_4_0_, this_.nameId as nameId5_4_0_, this_.ownerGUID as ownerGUI6_4_0_, this_.timeCreated as timeCrea7_4_0_, this_.valueId as valueId8_4_0_, this_.valueType as valueTyp9_4_0_ from METADATA this_ where (this_.accessId=? and this_.entityGUID=? and this_.nameId=? and this_.ownerGUID=? and this_.timeCreated=? and this_.valueId=?)

这些方法都不起作用。请帮我使它工作,以便我可以得到一个包含namenameId 两个数据对象的列表

更新:

数据库表实体类:

public class RevMetadata implements Serializable {
    private String name;
    private int valueId;

}

【问题讨论】:

  • 所以你想从 METADATA 做一个 SELECT name, valueId?
  • 是的,没错,@mylenereiners,但可以通过 Hibernate 的标准使其工作

标签: java sql hibernate


【解决方案1】:

如果要获取多列,需要将投影添加到 projectList 中:

Projections.projectionList()
.add(Projections.property("name"))
.add(Projections.property("valueId"))

c.list() 还返回一个List,并且此列表包含添加到您的projection list 的字段,因此它包含一个object array,第一个字段作为您的name 属性,第二个字段作为您的valueId 属性.所以你的c.list() 应该是这样的:

List<Object[]> rows = (List<Object[]>) c.list(); 

以下是有效的更改:

Criteria c = session.createCriteria(RevMetadata.class)
                .add(Restrictions.eq("entityGUID", GUID));

        c.setProjection(Projections.projectionList()
                .add(Projections.property("name"))
                .add(Projections.property("valueId")));

        List<Object[]> rows = (List<Object[]>) c.list(); 
        System.out.println(rows);
        for (Object[] row : rows) {
            System.out.println(row[0] + " and " + row[1]);
        }

【讨论】:

    【解决方案2】:

    如果只检索某些指定的列,则结果将为List&lt;Object[]&gt;

    在您的情况下,Object[] 将填充 name 值 => 索引 0nameId => 索引 1。需要将其转换为目标值的类型。

    Criteria criteria = session.createCriteria(RevMetadata.class);
    criteria.add(Restrictions.eq("entityGUID", GUID));
    
    criteria.setProjection(Projections.projectionList()
                            .add(Projections.property("name"))
                            .add(Projections.property("nameId")));
    
    List<Object[]> criteriaResult = criteria.list();
    
    List<RevMetadata> results = new ArrayList<RevMetadata>();
    //then get result into the class properties
    for (Object[] object : criteriaResult) {
        //cast to target value type
        String name = (String)object[0];
        int nameId = ((Integer)object[1]).intValue();
    
        RevMetadata result = new RevMetadata();
        result.setName(name);
        result.setValueId(nameId);
    
        results.add(result);
    }
    
    //now results of List<RevMetadata> is ready
    

    【讨论】:

    • 非常感谢@Wundwin Born。我真的不能感谢你。那真是太有见地了。谢谢
    • @user3663765 欢迎并很高兴听到它对您有所帮助:)
    【解决方案3】:
    List m = c.list();
        for(Iterator it = c.iterator(); it.hasNext()) {
            Object[] row = (Object[]) it.next();
            System.out.println("-> All entity metadata for GUID: " + row[0] + " : " +row[1]);
        }
    

    【讨论】:

    • 我这样做了,但现在我得到了错误:原因:java.lang.ClassCastException:java.lang.Integer 无法在 wakiliproject.Persistence.PersistRevMetadata.getAllEntityMetadata 中转换为 wakiliproject.Persistence.RevMetadata( PersistRevMetadata.java:114) 那一行: for (RevMetadata item : m) { Still not working!
    • 我认为,当您为您的意图添加一些解释时,这对 OP 和更多访问者会更有帮助。
    • 我尝试了您编辑的回复,但仍然没有成功。我收到错误java.lang.ClassCastException: java.lang.Integer cannot be cast to [Ljava.lang.Object;
    • Integer[] row = it.next();
    【解决方案4】:

    看来问题是双重转换

    (List<RevMetadata>) (RevMetadata) c.list();
    

    尝试移除演员表

    (RevMetadata)
    

    【讨论】:

    • 我这样做了,但现在我得到了错误:原因:java.lang.ClassCastException:java.lang.Integer 无法在 wakiliproject.Persistence.PersistRevMetadata.getAllEntityMetadata 中转换为 wakiliproject.Persistence.RevMetadata( PersistRevMetadata.java:114) 那一行: for (RevMetadata item : m) { Still not working!
    • 看来你遇到了一个普遍的问题。查看直接查询解决方案stackoverflow.com/questions/12618489/…
    猜你喜欢
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-14
    相关资源
    最近更新 更多