├── .gitignore
├── README.md
├── pom.xml
└── src
└── main
├── java
└── com
│ └── softwarehut
│ └── jpa
│ └── entityGraph
│ ├── Application.java
│ ├── CompanyController.java
│ ├── model
│ ├── Address.java
│ ├── Car.java
│ ├── Company.java
│ ├── Department.java
│ ├── Employee.java
│ └── Office.java
│ └── service
│ ├── CompanyService.java
│ ├── CompanyServiceCriteriaAPIImpl.java
│ ├── CompanyServiceEntityGraphImpl.java
│ └── CompanyServiceNamedQueryImpl.java
└── resources
├── application.properties
└── db
└── migration
└── h2
├── V1__create_address.sql
├── V2__create_car.sql
├── V3__create_company.sql
├── V4__create_department.sql
├── V5__create_employee.sql
├── V6__insert_car.sql
├── V7__create_office.sql
└── V8__insert_office.sql
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | .idea/
3 | *.class
4 | *.iml
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # EntityGraph
2 |
3 | [](https://codeclimate.com/github/adamzareba/EntityGraph)
4 |
5 | Example project for Spring Boot that uses JPA/Hibernate for querying data from database, exposed REST API that returns data querying for data structure:
6 |
7 | 
8 |
9 | Project demonstrates three different approaches for database querying:
10 | 1. Criteria API
11 | 2. Named Query
12 | 3. Named Entity Graph
13 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | entity-graph-jpa
8 | com.softwarehut
9 | 1.0-SNAPSHOT
10 |
11 |
12 | org.springframework.boot
13 | spring-boot-starter-parent
14 | 1.5.2.RELEASE
15 |
16 |
17 |
18 |
19 | org.springframework.boot
20 | spring-boot-starter-web
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-data-jpa
25 |
26 |
27 | org.hibernate
28 | hibernate-jpamodelgen
29 | 5.2.9.Final
30 |
31 |
32 | com.h2database
33 | h2
34 |
35 |
36 | org.flywaydb
37 | flyway-core
38 | 4.1.2
39 |
40 |
41 | com.fasterxml.jackson.datatype
42 | jackson-datatype-hibernate5
43 | 2.8.7
44 |
45 |
46 | org.projectlombok
47 | lombok
48 | 1.16.16
49 |
50 |
51 | org.springframework.boot
52 | spring-boot-starter-test
53 | test
54 |
55 |
56 |
57 |
58 | 1.8
59 |
60 |
61 |
62 |
63 |
64 | org.springframework.boot
65 | spring-boot-maven-plugin
66 |
67 |
68 | org.apache.maven.plugins
69 | maven-compiler-plugin
70 | 3.5.1
71 |
72 | 1.8
73 | 1.8
74 |
75 | true
76 | true
77 |
78 | org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor
79 |
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/src/main/java/com/softwarehut/jpa/entityGraph/Application.java:
--------------------------------------------------------------------------------
1 | package com.softwarehut.jpa.entityGraph;
2 |
3 | import com.fasterxml.jackson.databind.Module;
4 | import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
5 |
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.SpringBootApplication;
8 | import org.springframework.context.annotation.Bean;
9 |
10 | @SpringBootApplication
11 | public class Application {
12 |
13 | public static void main(String[] args) {
14 | SpringApplication.run(Application.class, args);
15 | }
16 |
17 | @Bean
18 | public Module hibernate5Module() {
19 | return new Hibernate5Module();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/softwarehut/jpa/entityGraph/CompanyController.java:
--------------------------------------------------------------------------------
1 | package com.softwarehut.jpa.entityGraph;
2 |
3 | import com.softwarehut.jpa.entityGraph.model.Company;
4 | import com.softwarehut.jpa.entityGraph.service.CompanyService;
5 |
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.beans.factory.annotation.Qualifier;
8 | import org.springframework.http.HttpStatus;
9 | import org.springframework.http.MediaType;
10 | import org.springframework.web.bind.annotation.PathVariable;
11 | import org.springframework.web.bind.annotation.RequestMapping;
12 | import org.springframework.web.bind.annotation.RequestMethod;
13 | import org.springframework.web.bind.annotation.ResponseStatus;
14 | import org.springframework.web.bind.annotation.RestController;
15 |
16 | @RestController
17 | @RequestMapping("/company/")
18 | public class CompanyController {
19 |
20 | @Autowired
21 | @Qualifier(value = "companyServiceEntityGraph")
22 | private CompanyService companyService;
23 |
24 | @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE, path = "/withDepartments/{companyId}")
25 | @ResponseStatus(value = HttpStatus.OK)
26 | public Company getCompanyWithDepartments(@PathVariable("companyId") Long companyId) {
27 | return companyService.getCompanyWithDepartments(companyId);
28 | }
29 |
30 | @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE, path = "/withDepartmentsAndEmployees/{companyId}")
31 | @ResponseStatus(value = HttpStatus.OK)
32 | public Company getCompanyWithDepartmentsAndEmployees(@PathVariable("companyId") Long companyId) {
33 | return companyService.getCompanyWithDepartmentsAndEmployees(companyId);
34 | }
35 |
36 | @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE, path = "/withDepartmentsAndEmployeesAndOffices/{companyId}")
37 | @ResponseStatus(value = HttpStatus.OK)
38 | public Company getCompanyWithDepartmentsAndEmployeesAndOffices(@PathVariable("companyId") Long companyId) {
39 | return companyService.getCompanyWithDepartmentsAndEmployeesAndOffices(companyId);
40 | }
41 |
42 | @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE, path = "/withCars/{companyId}")
43 | @ResponseStatus(value = HttpStatus.OK)
44 | public Company getCompanyWithCars(@PathVariable("companyId") Long companyId) {
45 | return companyService.getCompanyWithCars(companyId);
46 | }
47 |
48 | }
--------------------------------------------------------------------------------
/src/main/java/com/softwarehut/jpa/entityGraph/model/Address.java:
--------------------------------------------------------------------------------
1 | package com.softwarehut.jpa.entityGraph.model;
2 |
3 | import java.io.Serializable;
4 |
5 | import javax.persistence.Column;
6 | import javax.persistence.Entity;
7 | import javax.persistence.GeneratedValue;
8 | import javax.persistence.GenerationType;
9 | import javax.persistence.Id;
10 |
11 | import lombok.Getter;
12 | import lombok.Setter;
13 |
14 | @Entity
15 | @Getter
16 | @Setter
17 | public class Address implements Serializable {
18 |
19 | @Id
20 | @GeneratedValue(strategy = GenerationType.AUTO)
21 | @Column(name = "id", updatable = false, nullable = false)
22 | private Long id = null;
23 |
24 | private String street;
25 |
26 | private String houseNumber;
27 |
28 | private String zipCode;
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/softwarehut/jpa/entityGraph/model/Car.java:
--------------------------------------------------------------------------------
1 | package com.softwarehut.jpa.entityGraph.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonBackReference;
4 |
5 | import java.io.Serializable;
6 |
7 | import javax.persistence.Column;
8 | import javax.persistence.Entity;
9 | import javax.persistence.FetchType;
10 | import javax.persistence.GeneratedValue;
11 | import javax.persistence.GenerationType;
12 | import javax.persistence.Id;
13 | import javax.persistence.ManyToOne;
14 |
15 | import lombok.Getter;
16 | import lombok.Setter;
17 |
18 | @Entity
19 | @Getter
20 | @Setter
21 | public class Car implements Serializable {
22 |
23 | @Id
24 | @GeneratedValue(strategy = GenerationType.AUTO)
25 | @Column(name = "id", updatable = false, nullable = false)
26 | private Long id = null;
27 |
28 | private String registrationNumber;
29 |
30 | @ManyToOne(fetch = FetchType.LAZY)
31 | @JsonBackReference
32 | private Company company;
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/softwarehut/jpa/entityGraph/model/Company.java:
--------------------------------------------------------------------------------
1 | package com.softwarehut.jpa.entityGraph.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonManagedReference;
4 |
5 | import java.io.Serializable;
6 | import java.util.HashSet;
7 | import java.util.Set;
8 |
9 | import javax.persistence.Column;
10 | import javax.persistence.Entity;
11 | import javax.persistence.FetchType;
12 | import javax.persistence.GeneratedValue;
13 | import javax.persistence.GenerationType;
14 | import javax.persistence.Id;
15 | import javax.persistence.NamedAttributeNode;
16 | import javax.persistence.NamedEntityGraph;
17 | import javax.persistence.NamedEntityGraphs;
18 | import javax.persistence.NamedNativeQueries;
19 | import javax.persistence.NamedNativeQuery;
20 | import javax.persistence.NamedQueries;
21 | import javax.persistence.NamedQuery;
22 | import javax.persistence.NamedSubgraph;
23 | import javax.persistence.OneToMany;
24 |
25 | import lombok.Getter;
26 | import lombok.Setter;
27 |
28 | @Entity
29 | @NamedQueries({
30 | @NamedQuery(name = "companyWithDepartmentsNamedQuery",
31 | query = "SELECT DISTINCT c " +
32 | "FROM Company c " +
33 | "LEFT JOIN FETCH c.departments " +
34 | "WHERE c.id = :id"),
35 | @NamedQuery(name = "companyWithDepartmentsAndEmployeesNamedQuery",
36 | query = "SELECT DISTINCT c " +
37 | "FROM Company c " +
38 | "LEFT JOIN FETCH c.departments as d " +
39 | "LEFT JOIN FETCH d.employees " +
40 | "WHERE c.id = :id"),
41 | @NamedQuery(name = "companyWithDepartmentsAndEmployeesAndOfficesNamedQuery",
42 | query = "SELECT DISTINCT c " +
43 | "FROM Company c " +
44 | "LEFT JOIN FETCH c.departments as d " +
45 | "LEFT JOIN FETCH d.employees " +
46 | "LEFT JOIN FETCH d.offices " +
47 | "WHERE c.id = :id"),
48 | @NamedQuery(name = "companyWithCarsNamedQuery",
49 | query = "SELECT DISTINCT c " +
50 | "FROM Company c " +
51 | "LEFT JOIN FETCH c.cars " +
52 | "WHERE c.id = :id"),
53 | })
54 | @NamedEntityGraphs({
55 | @NamedEntityGraph(name = "companyWithDepartmentsGraph",
56 | attributeNodes = {@NamedAttributeNode("departments")}),
57 | @NamedEntityGraph(name = "companyWithDepartmentsAndEmployeesGraph",
58 | attributeNodes = {@NamedAttributeNode(value = "departments", subgraph = "departmentsWithEmployees")},
59 | subgraphs = @NamedSubgraph(
60 | name = "departmentsWithEmployees",
61 | attributeNodes = @NamedAttributeNode("employees"))),
62 | @NamedEntityGraph(name = "companyWithDepartmentsAndEmployeesAndOfficesGraph",
63 | attributeNodes = {@NamedAttributeNode(value = "departments", subgraph = "departmentsWithEmployeesAndOffices")},
64 | subgraphs = @NamedSubgraph(
65 | name = "departmentsWithEmployeesAndOffices",
66 | attributeNodes = {@NamedAttributeNode("employees"), @NamedAttributeNode("offices")}))
67 | })
68 | @Getter
69 | @Setter
70 | public class Company implements Serializable {
71 |
72 | @Id
73 | @GeneratedValue(strategy = GenerationType.AUTO)
74 | @Column(name = "id", updatable = false, nullable = false)
75 | private Long id = null;
76 |
77 | private String name;
78 |
79 | @OneToMany(mappedBy = "company", fetch = FetchType.LAZY)
80 | @JsonManagedReference
81 | private Set departments = new HashSet<>();
82 |
83 | @OneToMany(mappedBy = "company", fetch = FetchType.LAZY)
84 | @JsonManagedReference
85 | private Set cars = new HashSet<>();
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/softwarehut/jpa/entityGraph/model/Department.java:
--------------------------------------------------------------------------------
1 | package com.softwarehut.jpa.entityGraph.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonBackReference;
4 | import com.fasterxml.jackson.annotation.JsonManagedReference;
5 |
6 | import java.io.Serializable;
7 | import java.util.HashSet;
8 | import java.util.Set;
9 |
10 | import javax.persistence.Column;
11 | import javax.persistence.Entity;
12 | import javax.persistence.FetchType;
13 | import javax.persistence.GeneratedValue;
14 | import javax.persistence.GenerationType;
15 | import javax.persistence.Id;
16 | import javax.persistence.ManyToOne;
17 | import javax.persistence.OneToMany;
18 |
19 | import lombok.Getter;
20 | import lombok.Setter;
21 |
22 | @Entity
23 | @Getter
24 | @Setter
25 | public class Department implements Serializable {
26 |
27 | @Id
28 | @GeneratedValue(strategy = GenerationType.AUTO)
29 | @Column(name = "id", updatable = false, nullable = false)
30 | private Long id = null;
31 |
32 | private String name;
33 |
34 | @OneToMany(mappedBy = "department", fetch = FetchType.LAZY)
35 | @JsonManagedReference
36 | private Set employees = new HashSet<>();
37 |
38 | @OneToMany(mappedBy = "department", fetch = FetchType.LAZY)
39 | @JsonManagedReference
40 | private Set offices = new HashSet<>();
41 |
42 | @ManyToOne(fetch = FetchType.LAZY)
43 | @JsonBackReference
44 | private Company company;
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/softwarehut/jpa/entityGraph/model/Employee.java:
--------------------------------------------------------------------------------
1 | package com.softwarehut.jpa.entityGraph.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonBackReference;
4 |
5 | import java.io.Serializable;
6 |
7 | import javax.persistence.Column;
8 | import javax.persistence.Entity;
9 | import javax.persistence.FetchType;
10 | import javax.persistence.GeneratedValue;
11 | import javax.persistence.GenerationType;
12 | import javax.persistence.Id;
13 | import javax.persistence.JoinColumn;
14 | import javax.persistence.ManyToOne;
15 | import javax.persistence.NamedAttributeNode;
16 | import javax.persistence.NamedEntityGraph;
17 | import javax.persistence.NamedEntityGraphs;
18 | import javax.persistence.NamedSubgraph;
19 | import javax.persistence.OneToOne;
20 |
21 | import lombok.Getter;
22 | import lombok.Setter;
23 |
24 | @Entity
25 | @Getter
26 | @Setter
27 | public class Employee implements Serializable {
28 |
29 | @Id
30 | @GeneratedValue(strategy = GenerationType.AUTO)
31 | @Column(name = "id", updatable = false, nullable = false)
32 | private Long id = null;
33 |
34 | private String name;
35 |
36 | private String surname;
37 |
38 | @OneToOne(fetch = FetchType.LAZY)
39 | @JoinColumn(name = "address_id")
40 | private Address address;
41 |
42 | @ManyToOne(fetch = FetchType.LAZY)
43 | @JsonBackReference
44 | private Department department;
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/softwarehut/jpa/entityGraph/model/Office.java:
--------------------------------------------------------------------------------
1 | package com.softwarehut.jpa.entityGraph.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonBackReference;
4 |
5 | import java.io.Serializable;
6 |
7 | import javax.persistence.Column;
8 | import javax.persistence.Entity;
9 | import javax.persistence.FetchType;
10 | import javax.persistence.GeneratedValue;
11 | import javax.persistence.GenerationType;
12 | import javax.persistence.Id;
13 | import javax.persistence.JoinColumn;
14 | import javax.persistence.ManyToOne;
15 | import javax.persistence.OneToOne;
16 |
17 | import lombok.Getter;
18 | import lombok.Setter;
19 |
20 | @Entity
21 | @Getter
22 | @Setter
23 | public class Office implements Serializable {
24 |
25 | @Id
26 | @GeneratedValue(strategy = GenerationType.AUTO)
27 | @Column(name = "id", updatable = false, nullable = false)
28 | private Long id = null;
29 |
30 | private String name;
31 |
32 | @OneToOne(fetch = FetchType.LAZY)
33 | @JoinColumn(name = "address_id")
34 | private Address address;
35 |
36 | @ManyToOne(fetch = FetchType.LAZY)
37 | @JsonBackReference
38 | private Department department;
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/softwarehut/jpa/entityGraph/service/CompanyService.java:
--------------------------------------------------------------------------------
1 | package com.softwarehut.jpa.entityGraph.service;
2 |
3 | import com.softwarehut.jpa.entityGraph.model.Company;
4 |
5 | public interface CompanyService {
6 |
7 | Company getCompanyWithDepartments(Long companyId);
8 |
9 | Company getCompanyWithDepartmentsAndEmployees(Long companyId);
10 |
11 | Company getCompanyWithDepartmentsAndEmployeesAndOffices(Long companyId);
12 |
13 | Company getCompanyWithCars(Long companyId);
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/softwarehut/jpa/entityGraph/service/CompanyServiceCriteriaAPIImpl.java:
--------------------------------------------------------------------------------
1 | package com.softwarehut.jpa.entityGraph.service;
2 |
3 | import com.softwarehut.jpa.entityGraph.model.Company;
4 | import com.softwarehut.jpa.entityGraph.model.Company_;
5 | import com.softwarehut.jpa.entityGraph.model.Department;
6 | import com.softwarehut.jpa.entityGraph.model.Department_;
7 |
8 | import org.springframework.dao.support.DataAccessUtils;
9 | import org.springframework.stereotype.Service;
10 |
11 | import javax.persistence.EntityManager;
12 | import javax.persistence.PersistenceContext;
13 | import javax.persistence.criteria.CriteriaBuilder;
14 | import javax.persistence.criteria.CriteriaQuery;
15 | import javax.persistence.criteria.Fetch;
16 | import javax.persistence.criteria.JoinType;
17 | import javax.persistence.criteria.Predicate;
18 | import javax.persistence.criteria.Root;
19 |
20 | @Service(value = "companyServiceCriteriaAPI")
21 | public class CompanyServiceCriteriaAPIImpl implements CompanyService {
22 |
23 | @PersistenceContext
24 | private EntityManager entityManager;
25 |
26 | @Override
27 | public Company getCompanyWithDepartments(Long companyId) {
28 | CriteriaBuilder builder = entityManager.getCriteriaBuilder();
29 | CriteriaQuery query = builder.createQuery(Company.class);
30 |
31 | Root root = query.from(Company.class);
32 | root.fetch(Company_.departments, JoinType.LEFT);
33 |
34 | query.select(root).distinct(true);
35 | Predicate idPredicate = builder.equal(root.get(Company_.id), companyId);
36 | query.where(builder.and(idPredicate));
37 |
38 | return DataAccessUtils.singleResult(entityManager.createQuery(query).getResultList());
39 | }
40 |
41 | @Override
42 | public Company getCompanyWithDepartmentsAndEmployees(Long companyId) {
43 | CriteriaBuilder builder = entityManager.getCriteriaBuilder();
44 | CriteriaQuery query = builder.createQuery(Company.class);
45 |
46 | Root root = query.from(Company.class);
47 | Fetch departmentFetch = root.fetch(Company_.departments, JoinType.LEFT);
48 | departmentFetch.fetch(Department_.employees, JoinType.LEFT);
49 |
50 | query.select(root).distinct(true);
51 | Predicate idPredicate = builder.equal(root.get(Company_.id), companyId);
52 | query.where(builder.and(idPredicate));
53 |
54 | return DataAccessUtils.singleResult(entityManager.createQuery(query).getResultList());
55 | }
56 |
57 | @Override
58 | public Company getCompanyWithDepartmentsAndEmployeesAndOffices(Long companyId) {
59 | CriteriaBuilder builder = entityManager.getCriteriaBuilder();
60 | CriteriaQuery query = builder.createQuery(Company.class);
61 |
62 | Root root = query.from(Company.class);
63 | Fetch departmentFetch = root.fetch(Company_.departments, JoinType.LEFT);
64 | departmentFetch.fetch(Department_.employees, JoinType.LEFT);
65 | departmentFetch.fetch(Department_.offices, JoinType.LEFT);
66 |
67 | query.select(root).distinct(true);
68 | Predicate idPredicate = builder.equal(root.get(Company_.id), companyId);
69 | query.where(builder.and(idPredicate));
70 |
71 | return DataAccessUtils.singleResult(entityManager.createQuery(query).getResultList());
72 | }
73 |
74 | @Override
75 | public Company getCompanyWithCars(Long companyId) {
76 | CriteriaBuilder builder = entityManager.getCriteriaBuilder();
77 | CriteriaQuery query = builder.createQuery(Company.class);
78 |
79 | Root root = query.from(Company.class);
80 | root.fetch(Company_.cars, JoinType.LEFT);
81 |
82 | query.select(root).distinct(true);
83 | Predicate idPredicate = builder.equal(root.get(Company_.id), companyId);
84 | query.where(builder.and(idPredicate));
85 |
86 | return DataAccessUtils.singleResult(entityManager.createQuery(query).getResultList());
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/main/java/com/softwarehut/jpa/entityGraph/service/CompanyServiceEntityGraphImpl.java:
--------------------------------------------------------------------------------
1 | package com.softwarehut.jpa.entityGraph.service;
2 |
3 | import com.softwarehut.jpa.entityGraph.model.Company;
4 |
5 | import org.springframework.stereotype.Service;
6 |
7 | import java.util.HashMap;
8 | import java.util.Map;
9 |
10 | import javax.persistence.EntityGraph;
11 | import javax.persistence.EntityManager;
12 | import javax.persistence.PersistenceContext;
13 |
14 | @Service(value = "companyServiceEntityGraph")
15 | public class CompanyServiceEntityGraphImpl implements CompanyService {
16 |
17 | @PersistenceContext
18 | private EntityManager entityManager;
19 |
20 | @Override
21 | public Company getCompanyWithDepartments(Long companyId) {
22 | EntityGraph graph = entityManager.getEntityGraph("companyWithDepartmentsGraph");
23 | Map hints = new HashMap<>();
24 | hints.put("javax.persistence.fetchgraph", graph);
25 |
26 | return entityManager.find(Company.class, companyId, hints);
27 | }
28 |
29 | @Override
30 | public Company getCompanyWithDepartmentsAndEmployees(Long companyId) {
31 | EntityGraph graph = entityManager.getEntityGraph("companyWithDepartmentsAndEmployeesGraph");
32 | Map hints = new HashMap<>();
33 | hints.put("javax.persistence.fetchgraph", graph);
34 |
35 | return entityManager.find(Company.class, companyId, hints);
36 | }
37 |
38 | @Override
39 | public Company getCompanyWithDepartmentsAndEmployeesAndOffices(Long companyId) {
40 | EntityGraph graph = entityManager.getEntityGraph("companyWithDepartmentsAndEmployeesAndOfficesGraph");
41 | Map hints = new HashMap<>();
42 | hints.put("javax.persistence.fetchgraph", graph);
43 |
44 | return entityManager.find(Company.class, companyId, hints);
45 | }
46 |
47 | @Override
48 | public Company getCompanyWithCars(Long companyId) {
49 | EntityGraph graph = entityManager.createEntityGraph(Company.class);
50 | graph.addAttributeNodes("cars");
51 |
52 | Map hints = new HashMap<>();
53 | hints.put("javax.persistence.loadgraph", graph);
54 |
55 | return entityManager.find(Company.class, companyId, hints);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/com/softwarehut/jpa/entityGraph/service/CompanyServiceNamedQueryImpl.java:
--------------------------------------------------------------------------------
1 | package com.softwarehut.jpa.entityGraph.service;
2 |
3 | import com.softwarehut.jpa.entityGraph.model.Company;
4 |
5 | import org.springframework.dao.support.DataAccessUtils;
6 | import org.springframework.stereotype.Service;
7 |
8 | import javax.persistence.EntityManager;
9 | import javax.persistence.PersistenceContext;
10 | import javax.persistence.Query;
11 |
12 | @Service(value = "companyServiceNamedQuery")
13 | public class CompanyServiceNamedQueryImpl implements CompanyService {
14 |
15 | @PersistenceContext
16 | private EntityManager entityManager;
17 |
18 | @Override
19 | public Company getCompanyWithDepartments(Long companyId) {
20 | Query query = entityManager.createNamedQuery("companyWithDepartmentsNamedQuery")
21 | .setParameter("id", companyId);
22 |
23 | return (Company) DataAccessUtils.singleResult(query.getResultList());
24 | }
25 |
26 | @Override
27 | public Company getCompanyWithDepartmentsAndEmployees(Long companyId) {
28 | Query query = entityManager.createNamedQuery("companyWithDepartmentsAndEmployeesNamedQuery")
29 | .setParameter("id", companyId);
30 |
31 | return (Company) DataAccessUtils.singleResult(query.getResultList());
32 | }
33 |
34 | @Override
35 | public Company getCompanyWithDepartmentsAndEmployeesAndOffices(Long companyId) {
36 | Query query = entityManager.createNamedQuery("companyWithDepartmentsAndEmployeesAndOfficesNamedQuery")
37 | .setParameter("id", companyId);
38 |
39 | return (Company) DataAccessUtils.singleResult(query.getResultList());
40 | }
41 |
42 | @Override
43 | public Company getCompanyWithCars(Long companyId) {
44 | Query query = entityManager.createNamedQuery("companyWithCarsNamedQuery")
45 | .setParameter("id", companyId);
46 |
47 | return (Company) DataAccessUtils.singleResult(query.getResultList());
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.h2.console.enabled=true
2 | spring.h2.console.path=/console/
3 | logging.level.org.hibernate=debug
4 | spring.jpa.hibernate.ddl-auto=validate
5 |
6 | flyway.locations=db/migration/h2
--------------------------------------------------------------------------------
/src/main/resources/db/migration/h2/V1__create_address.sql:
--------------------------------------------------------------------------------
1 | create table address (id bigint generated by default as identity, house_number varchar(255), street varchar(255), zip_code varchar(255), primary key (id));
--------------------------------------------------------------------------------
/src/main/resources/db/migration/h2/V2__create_car.sql:
--------------------------------------------------------------------------------
1 | create table car (id bigint generated by default as identity, registration_number varchar(255), company_id bigint, primary key (id));
--------------------------------------------------------------------------------
/src/main/resources/db/migration/h2/V3__create_company.sql:
--------------------------------------------------------------------------------
1 | create table company (id bigint generated by default as identity, name varchar(255), primary key (id));
2 |
3 | alter table car add constraint FKjqp14dkmi2lh5kjavv4t0dkqy foreign key (company_id) references company;
--------------------------------------------------------------------------------
/src/main/resources/db/migration/h2/V4__create_department.sql:
--------------------------------------------------------------------------------
1 | create table department (id bigint generated by default as identity, name varchar(255), company_id bigint, primary key (id));
2 |
3 | alter table department add constraint FKh1m88q0f7sc0mk76kju4kcn6f foreign key (company_id) references company;
--------------------------------------------------------------------------------
/src/main/resources/db/migration/h2/V5__create_employee.sql:
--------------------------------------------------------------------------------
1 | create table employee (id bigint generated by default as identity, name varchar(255), surname varchar(255), address_id bigint, department_id bigint, primary key (id));
2 |
3 | alter table employee add constraint FKga73hdtpb67twlr9c1i337tyt foreign key (address_id) references address;
4 | alter table employee add constraint FKbejtwvg9bxus2mffsm3swj3u9 foreign key (department_id) references department;
--------------------------------------------------------------------------------
/src/main/resources/db/migration/h2/V6__insert_car.sql:
--------------------------------------------------------------------------------
1 | insert into company(id, name) values (1, 'Pepsi');
2 | insert into company(id, name) values (2, 'Coca Cola');
3 | insert into company(id, name) values (3, 'Sprite');
4 |
5 |
6 | insert into car(id, registration_number, company_id) values (1, 'XYZ10ABC', 1);
7 | insert into car(id, registration_number, company_id) values (2, 'XYZ11ABC', 1);
8 | insert into car(id, registration_number, company_id) values (3, 'XYZ12ABC', 1);
9 | insert into car(id, registration_number, company_id) values (4, 'XYZ13ABC', 2);
10 |
11 |
12 | insert into address(id, house_number, street, zip_code) VALUES (1, 1, 'Street X', '12-341');
13 | insert into address(id, house_number, street, zip_code) VALUES (2, 2, 'Street Y', '12-342');
14 | insert into address(id, house_number, street, zip_code) VALUES (3, 3, 'Street Z', '12-343');
15 | insert into address(id, house_number, street, zip_code) VALUES (4, 4, 'Street XX', '12-344');
16 | insert into address(id, house_number, street, zip_code) VALUES (5, 5, 'Street YY', '12-345');
17 | insert into address(id, house_number, street, zip_code) VALUES (6, 6, 'Street ZZ', '12-346');
18 | insert into address(id, house_number, street, zip_code) VALUES (7, 7, 'Street XXX', '12-347');
19 |
20 | insert into department(id, name, company_id) VALUES (1, 'Sales & Marketing', 1);
21 | insert into department(id, name, company_id) VALUES (2, 'Research & Development', 1);
22 | insert into department(id, name, company_id) VALUES (3, 'Administration', 1);
23 | insert into department(id, name, company_id) VALUES (4, 'Human Resources', 2);
24 | insert into department(id, name, company_id) VALUES (5, 'Sales & Marketing', 3);
25 |
26 | insert into employee(id, name, surname, address_id, department_id) VALUES (1, 'John', 'William', 1, 1);
27 | insert into employee(id, name, surname, address_id, department_id) VALUES (2, 'Robert', 'James', 2, 2);
28 | insert into employee(id, name, surname, address_id, department_id) VALUES (3, 'Donald', 'Tyler', 3, 3);
29 |
--------------------------------------------------------------------------------
/src/main/resources/db/migration/h2/V7__create_office.sql:
--------------------------------------------------------------------------------
1 | create table office (id bigint generated by default as identity, name varchar(255), address_id bigint, department_id bigint, primary key (id));
2 |
3 | alter table office add constraint FKga73hdtpb67twlr9c35357tyt foreign key (address_id) references address;
--------------------------------------------------------------------------------
/src/main/resources/db/migration/h2/V8__insert_office.sql:
--------------------------------------------------------------------------------
1 | insert into office(id, name, address_id, department_id) VALUES (1, 'Office of S&M Boston', 4, 1);
2 | insert into office(id, name, address_id, department_id) VALUES (2, 'Office of S&M New York', 5, 1);
3 | insert into office(id, name, address_id, department_id) VALUES (3, 'Office of R&D Boston', 6, 2);
4 | insert into office(id, name, address_id, department_id) VALUES (4, 'Office of A Los Angeles', 7, 3);
--------------------------------------------------------------------------------