// Path: jpa-example/src/main/java/com/codesod/example/jpa/nplusone/dto/PurchaseOrderDTO.java
// public class PurchaseOrderDTO {
//     private final String id;
//     private final OffsetDateTime orderDate;
// 
//     public PurchaseOrderDTO(String id, OffsetDateTime orderDate) {
//         this.id = id;
//         this.orderDate = orderDate;
//     }
// 
//     public String getId() {
//         return id;
//     }
// 
//     public OffsetDateTime getOrderDate() {
//         return orderDate;
//     }
// }
// 
// Path: jpa-example/src/main/java/com/codesod/example/jpa/nplusone/entity/PurchaseOrder.java
// @Entity
// public class PurchaseOrder {
// 
//     @Id
//     private String id;
//     private String customerId;
// 
//     @OneToMany(cascade = ALL, fetch = EAGER)
//     @JoinColumn(name = "purchase_order_id")
//     private List<PurchaseOrderItem> purchaseOrderItems = new ArrayList<>();
// 
//     private OffsetDateTime orderDate;
// 
//     public PurchaseOrder(String id, String customerId) {
//         this.id = id;
//         this.customerId = customerId;
//         this.orderDate = OffsetDateTime.now();
//     }
// 
//     public PurchaseOrder addOrderItem(PurchaseOrderItem purchaseOrderItem) {
//         purchaseOrderItems.add(purchaseOrderItem);
//         return this;
//     }
// 
//     private PurchaseOrder() {}
// 
//     public String getId() {
//         return id;
//     }
// 
//     public void setId(String id) {
//         this.id = id;
//     }
// 
//     public String getCustomerId() {
//         return customerId;
//     }
// 
//     public void setCustomerId(String customerId) {
//         this.customerId = customerId;
//     }
// 
//     public List<PurchaseOrderItem> getPurchaseOrderItems() {
//         return purchaseOrderItems;
//     }
// 
//     public void setPurchaseOrderItems(List<PurchaseOrderItem> purchaseOrderItems) {
//         this.purchaseOrderItems = purchaseOrderItems;
//     }
// 
//     public OffsetDateTime getOrderDate() {
//         return orderDate;
//     }
// 
//     public void setOrderDate(OffsetDateTime orderDate) {
//         this.orderDate = orderDate;
//     }
// }
// 
// Path: jpa-example/src/main/java/com/codesod/example/jpa/nplusone/repository/PurchaseOrderRepository.java
// @Repository
// public interface PurchaseOrderRepository extends JpaRepository<PurchaseOrder, String>,
//         JpaSpecificationExecutor<PurchaseOrder> {
// 
//     List<PurchaseOrder> findByCustomerId(String customerId);
// }


import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import com.codesod.example.jpa.nplusone.dto.PurchaseOrderDTO;
import com.codesod.example.jpa.nplusone.entity.PurchaseOrder;
import com.codesod.example.jpa.nplusone.repository.PurchaseOrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import java.util.Arrays;
/*
 * Copyright 2018 MD Sayem Ahmed
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.codesod.example.jpa.nplusone.service;






/**
 * @author MD Sayem Ahmed
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class PurchasingServiceIT {

    @Autowired
    private PurchasingService purchasingService;

    @PersistenceContext
    private EntityManager entityManager;

    @Test
    public void fetches_data_with_n_plus_1_queries() {
        // Given
        purchasingService.createOrder("Sayem", Arrays.asList("Harry Potter 1", "Harry Potter 2"));
        purchasingService.createOrder("Sayem", Arrays.asList("Harry Potter 3", "Harry Potter 4"));

        // When
        List<PurchaseOrder> ordersOfCustomer = purchasingService.findOrdersOfCustomer("Sayem");

        //Then
        assertThat(ordersOfCustomer).hasSize(2);
    }

    @Test
    public void fetches_a_tuple() {
        // Given
        purchasingService.createOrder("Sayem", Arrays.asList("Tin Goyenda", "Rupali Makorsha"));
        purchasingService.createOrder("Sayem", Arrays.asList("Roktochokhkhhu", "Kalo Beral"));

        // When
        TypedQuery<PurchaseOrderDTO> jpaQuery = entityManager.createQuery(
                "SELECT " +
                        "NEW com.codesod.example.jpa.nplusone.dto.PurchaseOrderDTO(P.id, P.orderDate) " +
                "FROM " +
                        "PurchaseOrder P " +
                "WHERE " +
                        "P.customerId = :customerId",
                PurchaseOrderDTO.class);
// Path: jpa-example/src/main/java/com/codesod/example/jpa/nplusone/dto/PurchaseOrderDTO.java
// public class PurchaseOrderDTO {
//     private final String id;
//     private final OffsetDateTime orderDate;
// 
//     public PurchaseOrderDTO(String id, OffsetDateTime orderDate) {
//         this.id = id;
//         this.orderDate = orderDate;
//     }
// 
//     public String getId() {
//         return id;
//     }
// 
//     public OffsetDateTime getOrderDate() {
//         return orderDate;
//     }
// }
// 
// Path: jpa-example/src/main/java/com/codesod/example/jpa/nplusone/entity/PurchaseOrder.java
// @Entity
// public class PurchaseOrder {
// 
//     @Id
//     private String id;
//     private String customerId;
// 
//     @OneToMany(cascade = ALL, fetch = EAGER)
//     @JoinColumn(name = "purchase_order_id")
//     private List<PurchaseOrderItem> purchaseOrderItems = new ArrayList<>();
// 
//     private OffsetDateTime orderDate;
// 
//     public PurchaseOrder(String id, String customerId) {
//         this.id = id;
//         this.customerId = customerId;
//         this.orderDate = OffsetDateTime.now();
//     }
// 
//     public PurchaseOrder addOrderItem(PurchaseOrderItem purchaseOrderItem) {
//         purchaseOrderItems.add(purchaseOrderItem);
//         return this;
//     }
// 
//     private PurchaseOrder() {}
// 
//     public String getId() {
//         return id;
//     }
// 
//     public void setId(String id) {
//         this.id = id;
//     }
// 
//     public String getCustomerId() {
//         return customerId;
//     }
// 
//     public void setCustomerId(String customerId) {
//         this.customerId = customerId;
//     }
// 
//     public List<PurchaseOrderItem> getPurchaseOrderItems() {
//         return purchaseOrderItems;
//     }
// 
//     public void setPurchaseOrderItems(List<PurchaseOrderItem> purchaseOrderItems) {
//         this.purchaseOrderItems = purchaseOrderItems;
//     }
// 
//     public OffsetDateTime getOrderDate() {
//         return orderDate;
//     }
// 
//     public void setOrderDate(OffsetDateTime orderDate) {
//         this.orderDate = orderDate;
//     }
// }
// 
// Path: jpa-example/src/main/java/com/codesod/example/jpa/nplusone/repository/PurchaseOrderRepository.java
// @Repository
// public interface PurchaseOrderRepository extends JpaRepository<PurchaseOrder, String>,
//         JpaSpecificationExecutor<PurchaseOrder> {
// 
//     List<PurchaseOrder> findByCustomerId(String customerId);
// }


// Path: jpa-example/src/test/java/com/codesod/example/jpa/nplusone/service/PurchasingServiceIT.java
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import com.codesod.example.jpa.nplusone.dto.PurchaseOrderDTO;
import com.codesod.example.jpa.nplusone.entity.PurchaseOrder;
import com.codesod.example.jpa.nplusone.repository.PurchaseOrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import java.util.Arrays;

/*
 * Copyright 2018 MD Sayem Ahmed
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.codesod.example.jpa.nplusone.service;






/**
 * @author MD Sayem Ahmed
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class PurchasingServiceIT {

    @Autowired
    private PurchasingService purchasingService;

    @PersistenceContext
    private EntityManager entityManager;

    @Test
    public void fetches_data_with_n_plus_1_queries() {
        // Given
        purchasingService.createOrder("Sayem", Arrays.asList("Harry Potter 1", "Harry Potter 2"));
        purchasingService.createOrder("Sayem", Arrays.asList("Harry Potter 3", "Harry Potter 4"));

        // When
        List<PurchaseOrder> ordersOfCustomer = purchasingService.findOrdersOfCustomer("Sayem");

        //Then
        assertThat(ordersOfCustomer).hasSize(2);
    }

    @Test
    public void fetches_a_tuple() {
        // Given
        purchasingService.createOrder("Sayem", Arrays.asList("Tin Goyenda", "Rupali Makorsha"));
        purchasingService.createOrder("Sayem", Arrays.asList("Roktochokhkhhu", "Kalo Beral"));

        // When
        TypedQuery<PurchaseOrderDTO> jpaQuery = entityManager.createQuery(
                "SELECT " +
                        "NEW com.codesod.example.jpa.nplusone.dto.PurchaseOrderDTO(P.id, P.orderDate) " +
                "FROM " +
                        "PurchaseOrder P " +
                "WHERE " +
                        "P.customerId = :customerId",
                PurchaseOrderDTO.class);
        jpaQuery.setParameter("customerId", "Sayem");