Search code examples
javahibernatehql

Hibernate Query Language: selecting some properties requires alias name


There are 3 classes in picture here: Employee.java, Department.java, and Designation.java

Here are the partial definitions of each...

Department.java

public class Department implements java.io.Serializable
{   private Integer id;
    private String name;
    // getters and setters for all propreties
}

Designation.java

public class Designation implements java.io.Serializable
{   private Integer id;
    private String name;
    // getters and setters for all propreties
}

Employee.java

public class Employee implements java.io.Serializable
{   private Integer id;
    private Employee reportingOfficer;
    private Department department;
    private Designation designation;
    private String loginId;
    // getters & setters for all propreties
}

I tried an HQL query that looked like this:

1st query

SELECT
  reportingOfficer
FROM
  data.persistence.ordb.Employee
WHERE
  department.name = 'Inventory Control'
  AND
  designation.name = 'Assistant Manager'

It gave me an error:

org.hibernate.hql.ast.QuerySyntaxException: Invalid Path: 'department.name'

But, I get correct results when I used an alias for data.persistence.ordb.Employee, as shown below:

2nd query

SELECT
  e.reportingOfficer
FROM
  data.persistence.ordb.Employee e
WHERE
  e.department.name = 'Inventory Control'
  AND
  e.designation.name = 'Assistant Manager'

Also, I do not get the Invalid Path error when I use this 3rd query: (Query that selects loginId of type String of reportingOfficer without alias name for Employee)

3rd query

SELECT
  reportingOfficer.loginId
FROM
  data.persistence.ordb.Employee
WHERE
  department.name = 'Inventory Control'
  AND
  designation.name = 'Assistant Manager'

But I get the same Invalid Path error when I use this 4th query: (intended to select designation of type Designation of reportingOfficer without alias name for Employee)

4th query

SELECT
  reportingOfficer.designation
FROM
  data.persistence.ordb.Employee
WHERE
  department.name = 'Inventory Control'
  AND
  designation.name = 'Assistant Manager'

And this 5th query gives correct results: (selects designation of type Designation of reportingOfficer with alias name for Employee)

5th query

SELECT
  e.reportingOfficer.designation
FROM
  data.persistence.ordb.Employee e
WHERE
  e.department.name = 'Inventory Control'
  AND
  e.designation.name = 'Assistant Manager'

My question is: Why the alias name is needed in case of 2nd & 5th queries, but not in 3rd query?


Solution

  • It's very simple:

    Both the entity you select from (Entity) and the entity you want to project (reportingOfficer) belong to the same entity type: Employee.

    public class Employee implements java.io.Serializable
        private Employee reportingOfficer;
    }
    

    If you don't use an alias, Hibernate will not know which "department" you are referring to. Is it the one you select from or the one you want to select (reportingOfficer).

    My golden rule is to always use aliases even when not necessary.

    Not using aliases is like relying on operator order instead of using parenthesis.