0

我有两个由外键关联的测试表

  • School(打开 fk student_id
  • Students(带有 pk id
  • FK:school.student_id -> students.id

如何使用此查询获取学生姓名?

Session session = DaoSF.getSessionFactory().openSession();
String query = "";
Query criteria;

query = "from School s " +
        "inner join s.student st " +
        "where s.student_id = st.id";
criteria = session.createQuery(query);

当我尝试迭代数据时:

for(Iterator<?> iter = criteria.iterate(); iter.hasNext();)
{
  Object item = (Object)iter.next();
  System.out.println(((School) item).getStudent().getId());
}

它报告:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to table.School

但映射工作正常,因为当我将最后一行更改为

System.out.println(item.toString());

我有所有的数据,但像这样:

[Ljava.lang.Object;@1d2300e
[Ljava.lang.Object;@51207c
[Ljava.lang.Object;@2bd615
...
4

2 回答 2

4

在 HQL 中,只要您在没有显式选择子句的情况下加入,Hibernate 就会返回所有加入的实体。这不是最直观的事情,但它是此时的遗留行为。

其次,您正在重新说明学校和学生之间的加入条件。您已经在映射中指定了这一点,所以当您在查询中说“join s.student”时,Hibernate 知道这一点。所以这里不需要 where 子句。

从大多数人对学校/学生关系的看法来看,您的数据模型似乎有点倒退。通常一所学校有多个学生(一个学生是与学校有特定关系的人)。但是鉴于您描述的模型...

您没有确切说明您想要从此查询中得到什么,但您的原始查询返回了所有学生。不知道为什么你甚至从 School 对象“驱动”查询。

Session session = ...;
List<Student> results = (List<Students>) session.createQuery( "select s from Students s" ).list();
for ( Student student : results ) {
    // handle each student
}

如果你只想要学生的名字(你有点/有点暗示):

Session session = ...;
List<String> results = (List<String>) session.createQuery( "select s.name from Students s" ).list();
for ( String student : results ) {
    // handle each student name
}

请注意,在我的上述查询中,select 子句实际上是可选的,因为 from 子句中只引用了一个实体。我更喜欢始终指定一个明确的选择子句。

于 2012-06-12T13:08:15.030 回答
0

您是迭代器的类型为 Object。尝试使用 School 输入。

for(Iterator<School> iter=criteria.iterate();iter.hasNext();){...}

由于这似乎不起作用,请尝试以下操作。

String sql="...";
Query query=session.createQuery(sql);
List<School> schools=(List<School>)query.list();
    for(School school:schools)
        System.out.println(school.getStudent().getId());
于 2012-06-12T12:00:40.833 回答