BAEL-2811: Added sample code for jpa joins (#6691)

This commit is contained in:
isa ölmez 2019-04-09 00:24:24 +03:00 committed by maibin
parent afd8fe5c98
commit 59f3b02e87
6 changed files with 302 additions and 0 deletions

View File

@ -0,0 +1,45 @@
package com.baeldung.joins.model;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
@Entity
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
@OneToMany(mappedBy = "department")
private List<Employee> employees;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
}

View File

@ -0,0 +1,69 @@
package com.baeldung.joins.model;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "joins_employee")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
private int age;
@ManyToOne
private Department department;
@OneToMany(mappedBy = "employee")
private List<Phone> phones;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public List<Phone> getPhones() {
return phones;
}
public void setPhones(List<Phone> phones) {
this.phones = phones;
}
}

View File

@ -0,0 +1,44 @@
package com.baeldung.joins.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
@Entity
public class Phone {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String number;
@ManyToOne
private Employee employee;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
}

View File

@ -0,0 +1 @@
spring.datasource.data=classpath:db/import_joins.sql

View File

@ -0,0 +1,13 @@
INSERT INTO department (id, name) VALUES (1, 'Infra');
INSERT INTO department (id, name) VALUES (2, 'Accounting');
INSERT INTO department (id, name) VALUES (3, 'Management');
INSERT INTO joins_employee (id, name, age, department_id) VALUES (1, 'Baeldung', '35', 1);
INSERT INTO joins_employee (id, name, age, department_id) VALUES (2, 'John', '35', 2);
INSERT INTO joins_employee (id, name, age, department_id) VALUES (3, 'Jane', '35', 2);
INSERT INTO phone (id, number, employee_id) VALUES (1, '111', 1);
INSERT INTO phone (id, number, employee_id) VALUES (2, '222', 1);
INSERT INTO phone (id, number, employee_id) VALUES (3, '333', 1);
COMMIT;

View File

@ -0,0 +1,130 @@
package com.baeldung.joins;
import static org.assertj.core.api.Assertions.assertThat;
import com.baeldung.joins.model.Department;
import com.baeldung.joins.model.Phone;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@DataJpaTest
@ActiveProfiles("joins")
public class JpaJoinsIntegrationTest {
@PersistenceContext
private EntityManager entityManager;
@Test
public void whenPathExpressionIsUsedForSingleValuedAssociation_thenCreatesImplicitInnerJoin() {
TypedQuery<Department> query = entityManager.createQuery("SELECT e.department FROM Employee e", Department.class);
List<Department> resultList = query.getResultList();
assertThat(resultList).hasSize(3);
assertThat(resultList).extracting("name")
.containsOnly("Infra", "Accounting", "Accounting");
}
@Test
public void whenJoinKeywordIsUsed_thenCreatesExplicitInnerJoin() {
TypedQuery<Department> query = entityManager.createQuery("SELECT d FROM Employee e JOIN e.department d", Department.class);
List<Department> resultList = query.getResultList();
assertThat(resultList).hasSize(3);
assertThat(resultList).extracting("name")
.containsOnly("Infra", "Accounting", "Accounting");
}
@Test
public void whenInnerJoinKeywordIsUsed_thenCreatesExplicitInnerJoin() {
TypedQuery<Department> query = entityManager.createQuery("SELECT d FROM Employee e INNER JOIN e.department d", Department.class);
List<Department> resultList = query.getResultList();
assertThat(resultList).hasSize(3);
assertThat(resultList).extracting("name")
.containsOnly("Infra", "Accounting", "Accounting");
}
@Test
public void whenEntitiesAreListedInFromAndMatchedInWhere_ThenCreatesJoin() {
TypedQuery<Department> query = entityManager.createQuery("SELECT d FROM Employee e, Department d WHERE e.department = d", Department.class);
List<Department> resultList = query.getResultList();
assertThat(resultList).hasSize(3);
assertThat(resultList).extracting("name")
.containsOnly("Infra", "Accounting", "Accounting");
}
@Test
public void whenEntitiesAreListedInFrom_ThenCreatesCartesianProduct() {
TypedQuery<Department> query = entityManager.createQuery("SELECT d FROM Employee e, Department d", Department.class);
List<Department> resultList = query.getResultList();
assertThat(resultList).hasSize(9);
assertThat(resultList).extracting("name")
.containsOnly("Infra", "Accounting", "Management", "Infra", "Accounting", "Management", "Infra", "Accounting", "Management");
}
@Test
public void whenCollectionValuedAssociationIsJoined_ThenCanSelect() {
TypedQuery<Phone> query = entityManager.createQuery("SELECT ph FROM Employee e JOIN e.phones ph ", Phone.class);
List<Phone> resultList = query.getResultList();
assertThat(resultList).hasSize(3);
}
@Test
public void whenMultipleEntitiesAreListedWithJoin_ThenCreatesMultipleJoins() {
TypedQuery<Phone> query = entityManager.createQuery("SELECT ph FROM Employee e JOIN e.department d JOIN e.phones ph WHERE d.name IS NOT NULL", Phone.class);
List<Phone> resultList = query.getResultList();
assertThat(resultList).hasSize(3);
assertThat(resultList).extracting("number")
.containsOnly("111", "222", "333");
}
@Test
public void whenLeftKeywordIsSpecified_thenCreatesOuterJoinAndIncludesNonMatched() {
TypedQuery<Department> query = entityManager.createQuery("SELECT DISTINCT d FROM Department d LEFT JOIN d.employees e", Department.class);
List<Department> resultList = query.getResultList();
assertThat(resultList).hasSize(3);
assertThat(resultList).extracting("name")
.containsOnly("Infra", "Accounting", "Management");
}
@Test
public void whenFetchKeywordIsSpecified_ThenCreatesFetchJoin() {
TypedQuery<Department> query = entityManager.createQuery("SELECT d FROM Department d JOIN FETCH d.employees", Department.class);
List<Department> resultList = query.getResultList();
assertThat(resultList).hasSize(3);
assertThat(resultList).extracting("name")
.containsOnly("Infra", "Accounting", "Accounting");
}
@Test
public void whenLeftAndFetchKeywordsAreSpecified_ThenCreatesOuterFetchJoin() {
TypedQuery<Department> query = entityManager.createQuery("SELECT d FROM Department d LEFT JOIN FETCH d.employees", Department.class);
List<Department> resultList = query.getResultList();
assertThat(resultList).hasSize(4);
assertThat(resultList).extracting("name")
.containsOnly("Infra", "Accounting", "Accounting", "Management");
}
}