在ManyToOne关系中解雇HQL

时间:2014-12-17 13:24:35

标签: java hibernate orm

我有大学和学生实体有OneToMany关系:

@Entity
public class College {

    @Id
    @GeneratedValue
    private int collegeId;

    private String collegeName;

    @OneToMany

    private Collection<Student> students = new ArrayList<Student>();

    public int getCollegeId() {
        return collegeId;
    }

    public void setCollegeId(int collegeId) {
        this.collegeId = collegeId;
    }

    public String getCollegeName() {
        return collegeName;
    }

    public void setCollegeName(String collegeName) {
        this.collegeName = collegeName;
    }

    public Collection<Student> getStudents() {
        return students;
    }
    public void setStudents(Collection<Student> students) {
        this.students = students;
    }
}

@Entity
public class Student {

    @Id
    @GeneratedValue
    private int studentId;

    private String studentName;


    public int getStudentId() {
        return studentId;
    }

    public void setStudentId(int studentId) {
        this.studentId = studentId;
    }

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

}

学生表中有大学的外键。

如果我想从一个特定的大学中取出所有学生,那么在原生SQL中,我可以使用以下查询:

Select * from student where collegeId=1

通过从学生实体中选择而不是从大学实体中选择,是否可以通过HQL 实现相同的目标。

我的实用程序类:

public class ManyToOne {

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("org.hibernate.examples");

        EntityManager em = emf.createEntityManager();
        College college1 = new College();
        college1.setCollegeName("College1");


        College college2 = new College();
        college2.setCollegeName("College2");

        Student student1 = new Student();
        student1.setStudentName("std1");

        college1.getStudents().add(student1);

        Student student2 = new Student();
        student2.setStudentName("std2");

        college2.getStudents().add(student2);

        Student student3 = new Student();
        student3.setStudentName("std3");

        college1.getStudents().add(student3);

        Student student4 = new Student();
        student4.setStudentName("std4");

        college1.getStudents().add(student4);

        em.getTransaction().begin();

        em.persist(college1);
        em.persist(college2);
        em.persist(student1);
        em.persist(student2);
        em.persist(student3);
        em.persist(student4);

        em.getTransaction().commit();
        em.close();

        em = emf.createEntityManager();
        em.getTransaction().begin();

        String queryString = "select students from "+ College.class.getName()+"   where collegeId = 1";

        Query query = em.createQuery(queryString);

        List<Student> students = query.getResultList();
        for(int i=0;i<students.size();i++)
            System.out.println(students.get(i).getStudentName());
        em.getTransaction().commit();
        em.close();
        emf.close();
    }
}

异常堆栈跟踪:

Exception in thread "main" java.lang.IllegalStateException: No data type for node: org.hibernate.hql.internal.ast.tree.IdentNode 
 \-[IDENT] IdentNode: 'students' {originalText=students}

    at org.hibernate.hql.internal.ast.tree.SelectClause.initializeExplicitSelectClause(SelectClause.java:174)
    at org.hibernate.hql.internal.ast.HqlSqlWalker.useSelectClause(HqlSqlWalker.java:924)
    at org.hibernate.hql.internal.ast.HqlSqlWalker.processQuery(HqlSqlWalker.java:692)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:665)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:249)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:158)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:131)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:93)
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:167)
    at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:301)
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236)
    at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1800)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:328)
    at utils.ManyToOne.main(ManyToOne.java:66)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

1 个答案:

答案 0 :(得分:1)

尝试使用此功能(只需在your other question中看到映射正常)

String queryString = "select s from Student s where s.college.collegeId = 1";

修改

关于你的评论,Hibernate有一个&#34;功能&#34;如果它找不到具有给定名称的字段,那么无论你给它什么,它都会传递给SQL。在你的情况下,它意味着

String queryString = "from Student where collegeId=1";

由于collegeId不是Student中的字段,它将按原样传递给SQL,从而产生您想要的查询。当然,缺点是将代码耦合到底层数据库模型,绕过ORM映射。