如何在Hibernate中返回特定类型的列表而不是List <object []>?</object []>

时间:2012-05-31 07:30:10

标签: java hibernate casting hql

我有课程树:

classA {  
      classB b;  
      classC c;
      .....
} 

我有这样的HQL查询:

SELECT a.field1, b.field2, c.field3, c.field4
FROM a LEFT OUTER JOIN b ON a.id = b.fk
       LEFT OUTER JOIN c ON b.id = c.fk 

此查询返回List<Object[]>

是否可以将返回的数据强制转换为以下类:

classD {
    Type1 fiedl1;
    Type2 field2;
    Type3 field3;
}

那么可以通过Hibernate进行转换,还是我需要手动完成所有的转换?

5 个答案:

答案 0 :(得分:24)

JPA查询中有不同类型的选择。 您目前正在使用Array作为返回类型,您需要的是构造返回类型。以下是如何实现此目的:

String queryStr =
    "select NEW package.YourDefinedCustomClass(
     a.field1, b.field2, c.field3, c.field4) from a left outer join b 
     on a.id=b.fk left outer join c on b.id=c.fk";

TypedQuery<YourDefinedCustomClass> query =
    em.createQuery(queryStr, YourDefinedCustomClass.class);

List<YourDefinedCustomClass> results = query.getResultList();

基本上有两件事:

  1. 自定义类必须是结果返回类型
  2. 自定义类必须具有构造函数,该构造函数接受您在查询字符串中定义的结果值。
  3. Read more on selects in JPA2 queries.

答案 1 :(得分:2)

您可以使用TypedQuery

TypedQuery<ClassA> q = em.createQuery("select a from a left outer join b on a.id=b.fk left outer join c on b.id=c.fk", ClassA.class); 
List<ClassA> res = q.getResultList(); 

答案 2 :(得分:1)

如果你确定你可以做类型演员。

 List<classD> newlist = ...;
 for(Object o : list){
      newlist.add((classD) o);
 }

虽然小心这个

是的。手动铸造。 (注意:有数组(你可以直接演员))

答案 3 :(得分:0)

我有同样的问题..我写了这个查询

Query sqlquery = session.createQuery("select c.courseName,f.facultyID,f.facultyName,f.facultyEmailID,f.facultyContactNo,s.subjectName from com.bean.CourseBean as c,com.bean.FacultyBean as f,com.bean.Faculty_SubjectBean as fs,com.bean.SubjectBean as s where f.facultyID=fs.facultyBean.facultyID AND s.subjectID=fs.subjectBean.subjectID AND c.courseID=f.courseBean.courseID AND collegeid=1");

我返回了对象列表,在我写的servlet中,

java.util.List objList = objFacultyService.listFaculty_sql(1);

java.util.List<Temp> objtemp = new ArrayList<Temp>() ;
for (Object[] objects : objList)
{


        Temp temp = new Temp();
        temp.setFacultyEmailID(objects[3].toString());
        temp.setCourseName(objects[0].toString());
        if(objects[4]==null)
        {
            temp.setFacultyContactNo(1);
        }
        else
        {
                  temp.setFacultyContactNo(Long.parseLong(objects[4].toString()));
        }
        temp.setFacultyID(Long.parseLong(objects[1].toString()));
        temp.setFacultyName(objects[2].toString());
        temp.setSubjectName(objects[5].toString());
        objtemp.add(temp);




}

答案 4 :(得分:0)

如果您使用的是Hibernate 5.x,则可以使用ResultTransformer,例如in this blog post中所述。请注意,ResultTransformer将在Hibernate 6中被@Deprecated。

适用于您的方案:

List<classD> classDDTOs = entityManager
.createQuery(
    "SELECT a.field1, b.field2, c.field3, c.field4 " +
    "FROM a LEFT OUTER JOIN b ON a.id = b.fk " +
    "LEFT OUTER JOIN c ON b.id = c.fk")
.unwrap( org.hibernate.query.Query.class )
.setResultTransformer( 
    new ResultTransformer() {
        @Override
        public Object transformTuple(
            Object[] tuple, 
            String[] aliases) {
            return new classD(
                (Type1) tuple[0],
                (Type2) tuple[1],
                (Type3) tuple[1],
            );
        }

        @Override
        public List transformList(List collection) {
            return collection;
        }
    } 
)
.getResultList();

以上代码假定classD具有构造函数classD(Type1, Type2, Type3)

此方法的优点是,它使您可以一次定义ResultTransformer,并允许您在具有相同结果类型的所有查询中重用它。