32

How can I write this SQL query in Hibernate? I would like to use Hibernate to create queries, not create the database.

SELECT * FROM Employee e INNER JOIN Team t ON e.Id_team=t.Id_team

I created entity classes in SQLServer2008,

@Entity
@Table(name="EMPLOYEE")
public class Employee
{
    @Id @GeneratedValue
    @Column(name="ID_EMPLOYEE")
    private int id_employee;
    @Column(name="SURNAME")
    private String surname;
    @Column(name="FIRSTNAME")
    private String firstname;
    @Column(name="ID_PROFESSION")
    private int id_profession;
    @Column(name="ID_BOSS")
    private int id_boss;
    @Column(name="HIRED_DATE")
    private Date hired;
    @Column(name="SALARY")
    private double salary;
    @Column(name="SALARY_ADD")
    private double salary_add;
    @Column(name="ID_TEAM")
    private int id_team;
    //setters and getters
}

@Entity
@Table(name="TEAM")
public class Team
{
    @Id @GeneratedValue
    @Column(name="ID_TEAM")
    private int id_team;
    @Column(name="TEAMNAME")
    private String teamname;
    @Column(name="ADDRESS")
    private String address;
    //setters and getters
}

I tried to build working select query in many ways but it still doesn't work.

SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();                 
session.beginTransaction();
String select = "FROM Employee e INNER JOIN Team t ON e.Id_team=t.Id_team";
Query query = session.createQuery(select);
List elist = query.list();
session.getTransaction().commit();
session.close();    

Maybe something is wrong with entities?

Peter Hall
  • 36,534
  • 10
  • 79
  • 144
szefu
  • 381
  • 1
  • 4
  • 10
  • by the way you added t.Id at the end of the query, but in your team entity, it is id_team. Could you change it to t.id_team – Burak Keceli Aug 22 '13 at 12:09
  • you incorrectly create enity classes. I think you need to rewrite and use such constructions like many-to-many, one-to-one or something like that – Aleksei Bulgak Aug 22 '13 at 12:13

3 Answers3

50

Joins can only be used when there is an association between entities. Your Employee entity should not have a field named id_team, of type int, mapped to a column. It should have a ManyToOne association with the Team entity, mapped as a JoinColumn:

@ManyToOne
@JoinColumn(name="ID_TEAM")
private Team team;

Then, the following query will work flawlessly:

select e from Employee e inner join e.team

Which will load all the employees, except those that aren't associated to any team.

The same goes for all the other fields which are a foreign key to some other table mapped as an entity, of course (id_boss, id_profession).

It's time for you to read the Hibernate documentation, because you missed an extremely important part of what it is and how it works.

JB Nizet
  • 633,450
  • 80
  • 1,108
  • 1,174
  • is it possible to create one to one association with Employee id_employee and Employee id_boss which must be removed as you wrote above? this is the same table (for example: a worker id_employee = 5 has a boss id_boss = 1 (who refers to id_employee=1), should I create: @OneToOne @JoinColumn(name="ID_EMPLOYEE") private Employee employee; // I would like to receive name of the boss, but this method doesnt work employeeList.getEmployee().getSurname(); – szefu Aug 22 '13 at 14:45
  • A boss has many employees, and an employee has a single boss, so it should be `@ManyToOne @JoinColumn(name="id_boss") private Employee boss` – JB Nizet Aug 22 '13 at 15:15
  • 1
    but the head boss doesn't have his own boss, so the value is in db null,how to do it in hibernate? – szefu Aug 22 '13 at 15:41
  • In this case, the boss field would simply be null. – JB Nizet Aug 22 '13 at 15:54
  • According to [this question](http://stackoverflow.com/questions/9892008): Hibernate can join entities that don't have an association in the mapping – Brel Apr 10 '15 at 13:05
  • It can only do inner joins. – JB Nizet Apr 10 '15 at 13:15
  • Guys, million dollar question is: how can you query team table, based on restrictions on employee table.. it seems like its impossible in hibernate ? Adding employee entity field to team is not a solution for me, team shouldnt know anything about employee. Btw its so hard to understand this hibernate.. it looks like its not done the way, they wanted to make it. – 10101101 Apr 25 '20 at 19:53
  • OK nevermind.. resolved issue with help of this JB Nizet answer here: https://stackoverflow.com/a/10448991/2457774 So thanks for Your help from the future xD Now got another problem.. after this query returns list, it has to update, by ajax, selectOne elements, and other selectOne elements.. – 10101101 Apr 25 '20 at 21:17
5
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name="empTable")
public class Employee implements Serializable{
private static final long serialVersionUID = 1L;
private int id;
private String empName;

List<Address> addList=new ArrayList<Address>();


@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="emp_id")
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public String getEmpName() {
    return empName;
}
public void setEmpName(String empName) {
    this.empName = empName;
}

@OneToMany(mappedBy="employee",cascade=CascadeType.ALL)
public List<Address> getAddList() {
    return addList;
}

public void setAddList(List<Address> addList) {
    this.addList = addList;
}
}

We have two entities Employee and Address with One to Many relationship.

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name="address")
public class Address implements Serializable{

private static final long serialVersionUID = 1L;

private int address_id;
private String address;
Employee employee;

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public int getAddress_id() {
    return address_id;
}
public void setAddress_id(int address_id) {
    this.address_id = address_id;
}
public String getAddress() {
    return address;
}
public void setAddress(String address) {
    this.address = address;
}

@ManyToOne
@JoinColumn(name="emp_id")
public Employee getEmployee() {
    return employee;
}
public void setEmployee(Employee employee) {
    this.employee = employee;
}
}

By this way we can implement inner join between two tables

import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;

public class Main {

public static void main(String[] args) {
    saveEmployee();

    retrieveEmployee();

}

private static void saveEmployee() {
    Employee employee=new Employee();
    Employee employee1=new Employee();
    Employee employee2=new Employee();
    Employee employee3=new Employee();

    Address address=new Address();
    Address address1=new Address();
    Address address2=new Address();
    Address address3=new Address();

    address.setAddress("1485,Sector 42 b");
    address1.setAddress("1485,Sector 42 c");
    address2.setAddress("1485,Sector 42 d");
    address3.setAddress("1485,Sector 42 a");

    employee.setEmpName("Varun");
    employee1.setEmpName("Krishan");
    employee2.setEmpName("Aasif");
    employee3.setEmpName("Dut");

    address.setEmployee(employee);
    address1.setEmployee(employee1);
    address2.setEmployee(employee2);
    address3.setEmployee(employee3);

    employee.getAddList().add(address);
    employee1.getAddList().add(address1);
    employee2.getAddList().add(address2);
    employee3.getAddList().add(address3);

    Session session=HibernateUtil.getSessionFactory().openSession();

    session.beginTransaction();

    session.save(employee);
    session.save(employee1);
    session.save(employee2);
    session.save(employee3);
    session.getTransaction().commit();
    session.close();
}

private static void retrieveEmployee() {
    try{

    String sqlQuery="select e from Employee e inner join e.addList";

    Session session=HibernateUtil.getSessionFactory().openSession();

    Query query=session.createQuery(sqlQuery);

    List<Employee> list=query.list();

     list.stream().forEach((p)->{System.out.println(p.getEmpName());});     
    session.close();
    }catch(Exception e){
        e.printStackTrace();
    }
}
}

I have used Java 8 for loop for priting the names. Make sure you have jdk 1.8 with tomcat 8. Also add some more records for better understanding.

 public class HibernateUtil {
 private static SessionFactory sessionFactory ;
 static {
    Configuration configuration = new Configuration();

    configuration.addAnnotatedClass(Employee.class);
    configuration.addAnnotatedClass(Address.class);
                  configuration.setProperty("connection.driver_class","com.mysql.jdbc.Driver");
    configuration.setProperty("hibernate.connection.url", "jdbc:mysql://localhost:3306/hibernate");                                
    configuration.setProperty("hibernate.connection.username", "root");     
    configuration.setProperty("hibernate.connection.password", "root");
    configuration.setProperty("dialect", "org.hibernate.dialect.MySQLDialect");
    configuration.setProperty("hibernate.hbm2ddl.auto", "update");
    configuration.setProperty("hibernate.show_sql", "true");
    configuration.setProperty(" hibernate.connection.pool_size", "10");


   // configuration
    StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
    sessionFactory = configuration.buildSessionFactory(builder.build());
 }
public static SessionFactory getSessionFactory() {
    return sessionFactory;
}
} 
Deepak
  • 1,532
  • 1
  • 16
  • 20
4

You can do it without having to create a real Hibernate mapping. Try this:

SELECT * FROM Employee e, Team t WHERE e.Id_team=t.Id_team
Val Blant
  • 1,456
  • 2
  • 22
  • 31
  • 4
    This results in cross join if I am not mistaken which would be extremely performance intensive as compared to inner join that it isn't worth the risk using it in a real application. – arunken Feb 12 '19 at 14:38
  • 5
    downvote because this is a cross join and will produce whole bunch of records as it is simply doing cartesian of two tables. – Pant Feb 18 '19 at 01:03