0

I have College and Student entities having OneToMany relationship:

@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;
    }

}

There is a foreign key to college in Student table.

If I want to fetch all students from a perticular college then in native SQL I can do tha with following query:

Select * from student where collegeId=1

Is it possible to achieve same with HQL by selecting from students entities and not from college entity.

My utility class:

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 stacktrace:

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)
vatsal mevada
  • 5,148
  • 7
  • 39
  • 68
  • Are these your real mappings? `@OneToMany` should have a `mappedBy` attribute set, and `Student` should have a relation to `College`. – Predrag Maric Dec 17 '14 at 13:30

1 Answers1

1

Try with this (just saw in your other question that mappings are ok)

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

EDIT

With regard to your comment, Hibernate has a "feature" where if it can't find a field with given name, it will just pass down to SQL whatever you give it. In your case it means that

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

since collegeId is not a field in Student, it will be passed into SQL as it is, resulting in the query you want. Of course, the downside is coupling of your code to underlying DB model, bypassing ORM mappings.

Community
  • 1
  • 1
Predrag Maric
  • 23,938
  • 5
  • 52
  • 68
  • :I have intentionally kept such mapping in this question. My question is for code given in this question. The other question you mentioned was different and your answer solved it and I have already accepted your answer.:) – vatsal mevada Dec 19 '14 at 07:36
  • I am facing following exception when I tried to execute query mentioned by you:java.lang.IllegalStateException: No data type for node: org.hibernate.hql.internal.ast.tree.IdentNode . I have added full stack-trace in question. – vatsal mevada Dec 19 '14 at 13:44
  • Not sure, but try this `String queryString = "from Student where collegeId=1";` – Predrag Maric Dec 19 '14 at 13:50
  • That fixed it. Removed "select *" from query and it is working fine. Thanks. – vatsal mevada Dec 22 '14 at 07:56