0

There are two beans : Dept and User. They map respectively table department and table employees :

    @Entity
    @Table(name = "HR.EMPLOYEES")
    public class User {

    @Id
    @SequenceGenerator(name="EMPLOYEES_SEQ", sequenceName="EMPLOYEES_SEQ", allocationSize=1)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="EMPLOYEES_SEQ")
    @Column(name = "EMPLOYEE_ID")
    private int uid;

    @Formula(value="FIRST_NAME || ' ' || LAST_NAME")
    private String username;

    @Column(name = "FIRST_NAME")
    private String firstname;

    @Column(name = "LAST_NAME")
    private String lastname;

    @Column(name="EMAIL")
    private String email;

    @Column(name="HIRE_DATE")
    @DateTimeFormat(pattern = "dd/MM/yyyy")
    private Date hireDate;

    private String job_id;

    @Column(name = "SALARY")
    private double salary;

    @ManyToOne
    @JoinColumn(name = "DEPARTMENT_ID")
    private Dept dept;

    public int getUid() {
        return uid;
    }
    public void setUid(int id) {
        this.uid = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getFirstname() {
        return firstname;
    }
    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }
    public String getLastname() {
        return lastname;
    }
    public void setLastname(String lastname) {
        this.lastname = lastname;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public Date getHireDate() {
        return hireDate;
    }
    public void setHireDate(Date hireDate) {
        this.hireDate = hireDate;
    }
    public String getJob_id() {
        return job_id;
    }
    public void setJob_id(String job_id) {
        this.job_id = job_id;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public Dept getDept() {
        return dept;
    }
    public void setDept(Dept dept) {
        this.dept = dept;
    }

}

@Entity
@Table(name = "HR.DEPARTMENTS")
public class Dept {

    @Id
    @Column(name = "DEPARTMENT_ID")
    private int id;

    @Column(name = "DEPARTMENT_NAME")
    private String dname;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "dept")
    @Transient
    private Set<User> users = new HashSet<User>(0);

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getDname() {
        return dname;
    }

    public void setDname(String dname) {
        this.dname = dname;
    }

    public Set<User> getUsers() {
        return users;
    }

    public void setUsers(Set<User> users) {
        this.users = users;
    }

}

Service method :

@Override
@Transactional
public List<User> list(int start, int length, String search, int triIdx, String ordreTri) {

    String hql = "from User u join u.dept as d "; // here is the join condition

    if (search != null && !search.equals("")) {

        hql = hql.concat(" where ");

        if (NumberUtils.isNumber(search))
            hql = hql.concat(" u.salary ");
        else
            hql = hql.concat(" lower(u.username) ");

        hql = hql.concat(" like '%").concat(search.toLowerCase()).concat("%'");

    }

    if (ordreTri.equals("asc")) {

        switch (triIdx) {
            case 0:
                hql = hql.concat(" order by u.username ");
                break;
            case 1:
                hql = hql.concat(" order by u.email ");
                break;
            case 2:
                hql = hql.concat(" order by u.salary ");
                break;
            case 3:
                hql = hql.concat(" order by d.dname ");
                break;
            default:
                hql = hql.concat(" order by u.username ");
                break;
        }

    } else {

        switch (triIdx) {
            case 0:
                hql = hql.concat(" order by u.username desc");
                break;
            case 1:
                hql = hql.concat(" order by u.email desc");
                break;
            case 2:
                hql = hql.concat(" order by u.salary desc");
                break;
            case 3:
                hql = hql.concat(" order by d.dname desc");
                break;
            default:
                hql = hql.concat(" order by u.username desc");
                break;
        }
    }

    Query query = sessionFactory.getCurrentSession().createQuery(hql);
    query = query.setFirstResult(start);
    query = query.setMaxResults(length);

    @SuppressWarnings("unchecked")
    List<User> listUser = (List<User>) query.list();
    return listUser;
}

dataTable :

...
"columns"       : [
                      {"data" : "username"},
                      {"data" : "email"},
                      {"data" : "salary"},
                      {"data" : "dname"},
                      {"data" : "uid"}
                  ],
...

I want to retrieve user columns and department name ; in standard SQL we can write : select e.first_name , e.salary, d.department_name from emp e join dept d on e.dept_id = d.dept_id

But how to write the join in Hibernate here ?

EDIT :

At runtime there is alert error : DataTables warning: table id=t_list - Requested unknown parameter 'username' for row 0, column 0. For more information about this error, please see http://datatables.net/tn/4

pheromix
  • 18,213
  • 29
  • 88
  • 158
  • do you want the specific columns? does `Criteria` object fit your needs? i mean, return the `User` object which has the `Dept` object as property. – Apostolos Sep 12 '16 at 09:48
  • ok if it is just hql, i guess you want `from User usr JOIN FETCH usr.dept` – Apostolos Sep 12 '16 at 09:53
  • `@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "DEPARTMENT_ID") private Dept dept;` – Apostolos Sep 12 '16 at 09:57
  • any updates? did you find it? – Apostolos Sep 13 '16 at 11:14
  • can you post the exception and the new code? – Apostolos Sep 13 '16 at 11:23
  • ok , I updated the source codes , and provided the error. – pheromix Sep 13 '16 at 11:38
  • ok this is `datatables` error. javascript-specific. nothing to do with the original question. does your hql return the data you want? – Apostolos Sep 13 '16 at 11:42
  • because of the datatable error nothing is displayed ! but I want to know if is the join condition correct this time ? – pheromix Sep 13 '16 at 11:46
  • you can `sysout` the results and see if it works the way you want, before trying to display them in a chosen UI mode (datatables at this specific situation). – Apostolos Sep 13 '16 at 11:49
  • sysout works when running the app on the IDE preview. How to do it if the app runs on browser ? – pheromix Sep 13 '16 at 11:51
  • so your query works as you asked for. that's what i wanted to know. this is a different question and you need to provide extra stuff about your templating engine, your html, js code etc. please accept an answer for this question to be considered closed. thnx. – Apostolos Sep 13 '16 at 11:59

1 Answers1

1

If you want to use hql, you can write

from User usr JOIN FETCH usr.dept

If you want to use Criteria object, you can write

CriteriaBuilder cb = your_entity_manager_object.getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery(User.class);
Root root = cq.from(User.class);
cq.select(root).distinct(true);
root.fetch(User_.dept, JoinType.INNER);

last line is valid only if you have enabled JPA 2.0 metamodel. See here

Community
  • 1
  • 1
Apostolos
  • 10,033
  • 5
  • 24
  • 39