An alias is useful when we want a relationship between tables and also when we want to refer to a field of the child object using a field of the parent object. So, an alias works as a bridge between them and is also used to refer to a field.
Let's consider one scenario. We have an Employee
and Department
relationship where each employee has only one department, but each department can be used multiple times for different employees. Add the following code to the respective files:
Source file: Employee.java
@Entity @Table public class Employee{ @Id @GeneratedValue private long id; @Column private String name; @ManyToOne @JoinColumn private Department department; // getters and setters }
Source file: Department.java
@Entity @Table public class Department{ @Id @GeneratedValue private long id; @Column private String name; // getters and setters }
Now, using the criteria of the Employee
class, we want to access a field name
of the Department
class. The following code shows the same.
First, we will take a look at what would happen if we did not use an alias. Execute the following code:
Criteria criteria = session.createCriteria(Employee.class); criteria.add(Restrictions.eq("department.name", "account")); List list = criteria.list();
The preceding code throws an error similar to could not resolve property: department.name of: Employee
.
Now, to resolve the error, we need to create an alias for the Department
class. Execute the following code:
/* Line 1 */ Criteria criteria = session.createCriteria(Employee.class); /* Line 2 */ criteria.createAlias("department", "dept"); /* Line 3 */ criteria.add(Restrictions.eq("dept.name", "account")); /* Line 4 */ List list = criteria.list();
Now it will work as expected.
Here, in Line 2
, we created an alias in the second code snippet. The createAlias(String, String)
method accepts both the parameters as string: the first is the instance variable of the referenced class (here, the Department
class), and the other is an alias name (here, dept
), which will be used further.
In Line 3
, we used the alias dept
to refer the name
field of the Department
class using the dept.name
code.
Line 4
actually makes the call to the database to get the data.
Let's consider a department that also refers to another class called Location
. In this case, let's take a look at how to refer to an attribute of the Location
class using the criteria of Employee
. Here, we will create a three-level hierarchy to make the example a bit more complex. Add the following code to the respective files:
Source file: Location.java
@Entity @Table public class Location{ @Id @GeneratedValue private long id; @Column private String name; // getters and setters }
Source file: Department.java
@Entity @Table public class Department{ @Id @GeneratedValue private long id; @Column private String name; @ManyToOne @JoinColumn private Location location; // getters and setters }
@Entity @Table public class Employee{ @Id @GeneratedValue private long id; @Column private String name; @ManyToOne @JoinColumn private Department department; // getters and setters }
Let's directly go to the code side:
/* Line 1 */ Criteria criteria = session.createCriteria(Employee.class); /* Line 3 */ criteria.createAlias("department", "dept"); /* Line 4 */ criteria.createAlias("dept.location", "loc"); /* Line 5 */ criteria.add(Restrictions.eq("loc.name", "AHD")); List list = criteria.list();
Here, we created a chain of aliases to refer to the subclasses. In Line 3
, we created an alias of the Department
class, which is dept
, and in Line 4
, we created an alias, "loc"
, which refers to the location class using the previous alias, "dept"
.