BAEL-7692
This commit is contained in:
parent
823bbbdae0
commit
35bdac1c59
persistence-modules/spring-data-jpa-repo-3/src
main/java/com/baeldung/spring/data/jpa/joinquery
test/java/com/baeldung/spring/data/jpa/joinquery
|
@ -0,0 +1,52 @@
|
|||
package com.baeldung.spring.data.jpa.joinquery;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Properties;
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
public class AppConfig {
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
|
||||
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
|
||||
emf.setDataSource(dataSource);
|
||||
emf.setPackagesToScan("com.baeldung.spring.data.jpa.joinquery.entities"
|
||||
, "com.baeldung.spring.data.jpa.joinquery.DTO"
|
||||
, "com.baeldung.spring.data.jpa.joinquery.repositories");
|
||||
emf.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
|
||||
emf.setJpaProperties(getHibernateProperties());
|
||||
return emf;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JpaTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) {
|
||||
return new JpaTransactionManager(entityManagerFactory.getObject());
|
||||
}
|
||||
|
||||
private Properties getHibernateProperties() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty("hibernate.hbm2ddl.auto", "create");
|
||||
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
package com.baeldung.spring.data.jpa.joinquery.DTO;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.IdClass;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
class DTO {
|
||||
private Long customer_id;
|
||||
private Long order_id;
|
||||
private Long product_id;
|
||||
|
||||
public DTO(Long customer_id, Long order_id, Long product_id) {
|
||||
this.customer_id = customer_id;
|
||||
this.order_id = order_id;
|
||||
this.product_id = product_id;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity
|
||||
@IdClass(DTO.class)
|
||||
public class ResultDTO {
|
||||
@Id
|
||||
private Long customer_id;
|
||||
|
||||
@Id
|
||||
private Long order_id;
|
||||
|
||||
@Id
|
||||
private Long product_id;
|
||||
|
||||
public void setCustomer_id(Long customer_id) {
|
||||
this.customer_id = customer_id;
|
||||
}
|
||||
|
||||
public Long getProduct_id() {
|
||||
return product_id;
|
||||
}
|
||||
|
||||
public void setProduct_id(Long product_id) {
|
||||
this.product_id = product_id;
|
||||
}
|
||||
|
||||
public ResultDTO(Long customer_id, Long order_id, Long product_id, String customerName, String customerEmail, LocalDate orderDate, String productName, Double productPrice) {
|
||||
this.customer_id = customer_id;
|
||||
this.order_id = order_id;
|
||||
this.product_id = product_id;
|
||||
this.customerName = customerName;
|
||||
this.customerEmail = customerEmail;
|
||||
this.orderDate = orderDate;
|
||||
this.productName = productName;
|
||||
this.productPrice = productPrice;
|
||||
}
|
||||
|
||||
private String customerName;
|
||||
private String customerEmail;
|
||||
private LocalDate orderDate;
|
||||
private String productName;
|
||||
private Double productPrice;
|
||||
|
||||
public Long getCustomer_id() {
|
||||
return customer_id;
|
||||
}
|
||||
|
||||
public void setCustoemr_id(Long custoemr_id) {
|
||||
this.customer_id = custoemr_id;
|
||||
}
|
||||
|
||||
public String getCustomerName() {
|
||||
return customerName;
|
||||
}
|
||||
|
||||
public void setCustomerName(String customerName) {
|
||||
this.customerName = customerName;
|
||||
}
|
||||
|
||||
public String getCustomerEmail() {
|
||||
return customerEmail;
|
||||
}
|
||||
|
||||
public void setCustomerEmail(String customerEmail) {
|
||||
this.customerEmail = customerEmail;
|
||||
}
|
||||
|
||||
public Long getOrder_id() {
|
||||
return order_id;
|
||||
}
|
||||
|
||||
public void setOrder_id(Long order_id) {
|
||||
this.order_id = order_id;
|
||||
}
|
||||
|
||||
public LocalDate getOrderDate() {
|
||||
return orderDate;
|
||||
}
|
||||
|
||||
public void setOrderDate(LocalDate orderDate) {
|
||||
this.orderDate = orderDate;
|
||||
}
|
||||
|
||||
public String getProductName() {
|
||||
return productName;
|
||||
}
|
||||
|
||||
public void setProductName(String productName) {
|
||||
this.productName = productName;
|
||||
}
|
||||
|
||||
public Double getProductPrice() {
|
||||
return productPrice;
|
||||
}
|
||||
|
||||
public void setProductPrice(Double productPrice) {
|
||||
this.productPrice = productPrice;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
package com.baeldung.spring.data.jpa.joinquery.entities;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
@Entity
|
||||
public class Customer {
|
||||
public Customer(){}
|
||||
@Id
|
||||
//@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@OneToMany(mappedBy = "customer"
|
||||
, cascade = CascadeType.ALL)
|
||||
private Set<CustomerOrder> customerOrders;
|
||||
|
||||
public Customer(Long id, Set<CustomerOrder> customerOrders, String email, LocalDate dob, String name) {
|
||||
this.id = id;
|
||||
this.customerOrders = customerOrders;
|
||||
this.email = email;
|
||||
this.dob = dob;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setCustomerOrders(Set<CustomerOrder> customerOrders) {
|
||||
this.customerOrders = customerOrders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Patient{" +
|
||||
"id=" + id +
|
||||
", orders=" + customerOrders +
|
||||
", email='" + email + '\'' +
|
||||
", dob=" + dob +
|
||||
", name='" + name + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
public Set<CustomerOrder> getOrders() {
|
||||
return customerOrders;
|
||||
}
|
||||
|
||||
public void setOrders(Set<CustomerOrder> orders) {
|
||||
this.customerOrders = orders;
|
||||
}
|
||||
|
||||
@Column
|
||||
private String email;
|
||||
|
||||
@Column(name = "dob", columnDefinition = "DATE")
|
||||
private LocalDate dob;
|
||||
|
||||
@Column
|
||||
private String name;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Customer patient = (Customer) o;
|
||||
return Objects.equals(id, patient.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public LocalDate getDob() {
|
||||
return dob;
|
||||
}
|
||||
|
||||
public void setDob(LocalDate dob) {
|
||||
this.dob = dob;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package com.baeldung.spring.data.jpa.joinquery.entities;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
@Entity
|
||||
public class CustomerOrder {
|
||||
public CustomerOrder(){}
|
||||
@Id
|
||||
//@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Set<Product> getProducts() {
|
||||
return products;
|
||||
}
|
||||
|
||||
public void setProducts(Set<Product> products) {
|
||||
this.products = products;
|
||||
}
|
||||
|
||||
@OneToMany(mappedBy = "customerOrder"
|
||||
, cascade = CascadeType.ALL)
|
||||
private Set<Product> products;
|
||||
|
||||
@Column
|
||||
private LocalDate orderDate;
|
||||
|
||||
public CustomerOrder(Long id, Set<Product> products, LocalDate orderDate, Customer customer) {
|
||||
this.id = id;
|
||||
this.products = products;
|
||||
this.orderDate = orderDate;
|
||||
this.customer = customer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Consult{" +
|
||||
"id=" + id +
|
||||
", products=" + products +
|
||||
", orderDate=" + orderDate +
|
||||
", customer=" + customer +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
CustomerOrder co = (CustomerOrder) o;
|
||||
return Objects.equals(id, co.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name="customer_id", nullable = false)
|
||||
private Customer customer;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public LocalDate getOrderDate() {
|
||||
return orderDate;
|
||||
}
|
||||
|
||||
public void setOrderDate(LocalDate orderDate) {
|
||||
this.orderDate = orderDate;
|
||||
}
|
||||
|
||||
public Customer getCustomer() {
|
||||
return customer;
|
||||
}
|
||||
|
||||
public void setCustomer(Customer customer) {
|
||||
this.customer = customer;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package com.baeldung.spring.data.jpa.joinquery.entities;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
public class Product {
|
||||
public Product(){}
|
||||
@Id
|
||||
//@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
public Product(Long id, String productName, Double price, CustomerOrder customerOrder) {
|
||||
this.id = id;
|
||||
this.productName = productName;
|
||||
this.price = price;
|
||||
this.customerOrder = customerOrder;
|
||||
}
|
||||
|
||||
@Column
|
||||
private String productName;
|
||||
|
||||
@Column
|
||||
private Double price;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Dispense{" +
|
||||
"id=" + id +
|
||||
", productName='" + productName + '\'' +
|
||||
", price=" + price +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Product dispense = (Product) o;
|
||||
return Objects.equals(id, dispense.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getProductName() {
|
||||
return productName;
|
||||
}
|
||||
|
||||
public void setProductName(String productName) {
|
||||
this.productName = productName;
|
||||
}
|
||||
|
||||
public Double getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(Double price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public CustomerOrder getCustomerOrder() {
|
||||
return customerOrder;
|
||||
}
|
||||
|
||||
public void setCustomerOrder(CustomerOrder co) {
|
||||
this.customerOrder = co;
|
||||
}
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name="customerorder_id", nullable = false)
|
||||
private CustomerOrder customerOrder;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.baeldung.spring.data.jpa.joinquery.repositories;
|
||||
|
||||
import com.baeldung.spring.data.jpa.joinquery.entities.Customer;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface CustomerRepository extends CrudRepository<Customer, Long> {
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.spring.data.jpa.joinquery.repositories;
|
||||
|
||||
import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Repository
|
||||
public interface JoinRepository extends CrudRepository<ResultDTO, Long> {
|
||||
@Query(value = "SELECT new com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO(c.id, o.id, p.id, c.name, c.email, o.orderDate, p.productName, p.price) "
|
||||
+ " from Customer c, CustomerOrder o ,Product p "
|
||||
+ " where c.id=o.customer.id "
|
||||
+ " and o.id=p.customerOrder.id "
|
||||
+ " and c.id=?1 ")
|
||||
List<ResultDTO> findResultDTOByCustomer(Long id);
|
||||
|
||||
@Query(value = "SELECT c.*, o.*, p.* "
|
||||
+ " from Customer c, CustomerOrder o ,Product p "
|
||||
+ " where c.id=o.customer_id "
|
||||
+ " and o.id=p.customerOrder_id "
|
||||
+ " and c.id=?1 "
|
||||
, nativeQuery = true)
|
||||
List<Map<String, Object>> findByCustomer(Long id);
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package com.baeldung.spring.data.jpa.joinquery;
|
||||
|
||||
import com.baeldung.spring.data.jpa.joinquery.entities.Customer;
|
||||
import com.baeldung.spring.data.jpa.joinquery.entities.CustomerOrder;
|
||||
import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO;
|
||||
import com.baeldung.spring.data.jpa.joinquery.entities.Product;
|
||||
import com.baeldung.spring.data.jpa.joinquery.repositories.CustomerRepository;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.EntityManagerFactory;
|
||||
import jakarta.persistence.EntityTransaction;
|
||||
import jakarta.persistence.PersistenceUnit;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import com.baeldung.spring.data.jpa.joinquery.repositories.JoinRepository;
|
||||
import java.time.LocalDate;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration(classes = { AppConfig.class })
|
||||
class JoinRepositoryTest {
|
||||
|
||||
@Autowired
|
||||
JoinRepository joinRepository;
|
||||
|
||||
@Autowired
|
||||
CustomerRepository customerRepository;
|
||||
|
||||
@PersistenceUnit
|
||||
EntityManagerFactory entityManagerFactory;
|
||||
|
||||
EntityManager entityManager;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
customerRepository.deleteAll();
|
||||
entityManager = entityManagerFactory.createEntityManager();
|
||||
Customer c = new Customer(1L, null, "email1@email.com", LocalDate.now(), "Customer");
|
||||
CustomerOrder o1 = new CustomerOrder(1L, null, LocalDate.now(), c);
|
||||
CustomerOrder o2 = new CustomerOrder(2L, null, LocalDate.of(2024,1,1), c);
|
||||
|
||||
Product p1 = new Product(1L,"Product1", 25.20, o1);
|
||||
Product p2 = new Product(2L, "Product2", 26.20, o1);
|
||||
Product p3 = new Product(3L, "Product3", 27.20, o2);
|
||||
|
||||
Set<CustomerOrder> cos01 = new HashSet<>();
|
||||
cos01.add(o1);
|
||||
cos01.add(o2);
|
||||
Set<Product> productsO1 = new HashSet<>();
|
||||
productsO1.add(p1);
|
||||
productsO1.add(p2);
|
||||
Set<Product> productsO2 = new HashSet<>();
|
||||
productsO1.add(p3);
|
||||
|
||||
c.setCustomerOrders(cos01);
|
||||
o1.setProducts(productsO1);
|
||||
o2.setProducts(productsO2);
|
||||
|
||||
EntityTransaction et = getTransaction();
|
||||
entityManager.persist(c);
|
||||
entityManager.flush();
|
||||
et.commit();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenFindResultDTOByCustomer_thenReturnResultDTO() {
|
||||
List<ResultDTO> resultDTO = joinRepository.findResultDTOByCustomer(1L);
|
||||
assertInstanceOf(ResultDTO.class, resultDTO.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenFindByCustomerNativeQuery_thenReturnMapsForObjects() {
|
||||
List<Map<String, Object>> res = joinRepository.findByCustomer(1L);
|
||||
//the map objects in the res List has 9 String keys aka 9 columns corresponding to the columns of customer, customerOrder, product
|
||||
res.forEach(map -> {
|
||||
assertEquals(9, map.keySet().size());
|
||||
});
|
||||
}
|
||||
private EntityTransaction getTransaction() {
|
||||
EntityTransaction transaction = entityManager.getTransaction();
|
||||
transaction.begin();
|
||||
return transaction;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue