Необходимо вернуть список настраиваемых объектов с помощью JPA @Query

У меня есть нестандартный объект

@Component
public class SaleReport {

    private Date date;
    private String customerName;
    private String phoneNo;
    private String productName;
    private Integer quantity;
    private Double totalAmount;

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

    public String getPhoneNo() {
        return phoneNo;
    }

    public void setPhoneNo(String phoneNo) {
        this.phoneNo = phoneNo;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public Integer getQuantity() {
        return quantity;
    }

    public void setQuantity(Integer quantity) {
        this.quantity = quantity;
    }

    public Double getTotalAmount() {
        return totalAmount;
    }

    public void setTotalAmount(Double totalAmount) {
        this.totalAmount = totalAmount;
    }
}

Мне нужно вернуть список этого объекта с помощью JpaRepository<Sale, Integer>SaleRepository выглядит следующим образом:

@Repository
public interface SaleRepository extends JpaRepository<Sale, Integer> {


    @Query(value = "SELECT B.order_date AS date, E.customer_name AS customerName, " +
            "E.phone_no AS phoneNo, D.product_name AS productName, C.quantity AS quantity, " +
            "C.total_price AS totalAmount " +
            "FROM SALE A " +
            "INNER JOIN A.quotation_id B " +
            "INNER JOIN B.quotation_id C " +
            "INNER JOIN C.product_id D " +
            "INNER JOIN B.customer_id E " +
            "WHERE (B.order_date BETWEEN :from_date AND :to_date)", nativeQuery = true)
    public List<SaleReport> getSaleReportByDate(@Param("from_date")String fromDate, @Param("to_date")String toDate);

}

Вот мой метод контроллера:

@GetMapping("api/report/sale/{from_date}/{to_date}")
        public List<SaleReport> getSaleReportByDate(@PathVariable("from_date") String fromDate, @PathVariable("to_date") String toDate){
        return saleRepository.getSaleReportByDate(fromDate, toDate);
}

Пока я запускаю код, он показывает эту ошибку:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'a'
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_161]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_161]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_161]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_161]
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) ~[mysql-connector-java-5.1.47.jar:5.1.47]
    at com.mysql.jdbc.Util.getInstance(Util.java:408) ~[mysql-connector-java-5.1.47.jar:5.1.47]
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:944) ~[mysql-connector-java-5.1.47.jar:5.1.47]

Мое НАЗВАНИЕ БАЗЫ ДАННЫХ в порядке. Он отлично работает, пока я запрашиваю другие методы. Пожалуйста, предложите мне идеальное решение.

Это исключение связано с тем, что приложение не может найти имя базы данных. Убедитесь, что у вас есть база данных с именем 'a', проверив вручную.

Alien 02.11.2018 08:34

Почему запрос ищет базу данных с именем 'a' ..? Вот информация о моей базе данных spring.datasource.url=jdbc:mysql://localhost:3366/andropos_d‌​b spring.datasource.username=root spring.datasource.password=1525

Mehedi Hasan Chonchol 02.11.2018 08:37

ОТ ПРОДАЖИ A "+" ВНУТРЕННЕЕ СОЕДИНЕНИЕ A.quotation_id B "+ посмотрите это. Вы пытаетесь сделать что-то только с базой данных 'a'

Alien 02.11.2018 08:39

Я заменил SALE A на Только SALE. в этом случае запрос ищет базу данных с именем «продажа». Что теперь?

Mehedi Hasan Chonchol 02.11.2018 08:49

SaleReport с пометкой «Компонент». Я думаю, это должно быть помечено "Entity"?

Habil 02.11.2018 08:56

@Habil это не организация.

Mehedi Hasan Chonchol 02.11.2018 09:08
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
6
9 223
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

1) Вам необходимо создать конструктор для класса SaleReport, который принимает все параметры, которые вы используете в операторе select, и в точном порядке.

2) Измените свой запрос, чтобы обернуть выбранные столбцы оператором new:

@Query(value = "SELECT new org.mypackage.SaleReport(B.order_date AS date,"
                        + "E.customer_name AS customerName, "
                        + "E.phone_no AS phoneNo, D.product_name AS productName, 
                        + "C.quantity AS quantity, " +
                        + "C.total_price AS totalAmount) " +
            "FROM SALE A " +
            "INNER JOIN A.quotation B " +
            "INNER JOIN B.quotation C " +
            "INNER JOIN C.product D " +
            "INNER JOIN B.customer E " +
            "WHERE (B.order_date BETWEEN :from_date AND :to_date)") 

3) На мой взгляд, вам здесь не нужен собственный запрос, и вы можете напрямую использовать HQL (измененные объединения).

Показывает следующую ошибку: org.springframework.beans.factory.UnsatisfiedDependencyExcep‌​tion: Error creating bean with name 'saleController': Unsatisfied dependency expressed through field 'saleRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'saleRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List me.chonchol.androposweb.repository.SaleRepository.getSaleRep‌​ortByDate(java.lang.‌​String,java.lang.Str‌​ing)!

Mehedi Hasan Chonchol 02.11.2018 09:33

Убедитесь, что вы используете имена переменных экземпляра сущности вместо прямых имен столбцов базы данных.

Maciej Kowalski 02.11.2018 09:36
Ответ принят как подходящий

В Spring есть аннотация под названием @SqlResultSetMapping. Эту аннотацию можно использовать для решения указанной выше проблемы. Подробности об этой аннотации можно найти по следующей ссылке:

Конструктор типа аннотации Результат

Это фактически отображает результат запроса гибернации в простой класс POJO. Вот что действительно нужно.

Example:

   Query q = em.createNativeQuery(
      "SELECT c.id, c.name, COUNT(o) as orderCount, AVG(o.price) AS avgOrder " +
      "FROM Customer c, Orders o " +
      "WHERE o.cid = c.id " +
      "GROUP BY c.id, c.name",
      "CustomerDetailsResult");

   @SqlResultSetMapping(
       name = "CustomerDetailsResult",
       classes = {
          @ConstructorResult(
               targetClass=com.acme.CustomerDetails.class,
                 columns = {
                    @ColumnResult(name = "id"),
                    @ColumnResult(name = "name"),
                    @ColumnResult(name = "orderCount"),
                    @ColumnResult(name = "avgOrder", type=Double.class)
                    }
          )
       }
      )

Поместите @SqlResultSetMapping поверх любого @Entity и убедитесь, что datatype, возвращаемый из базы данных, совпадает с вашим POJO класса datatype.

Надеюсь, что это поможет вам. Наслаждаться :)

Надеюсь, этот ответ может вам помочь !!

распродажа - это ваш класс сущности и класс SaleReport is pojo.

public List<SaleReport> getSaleReportByDate(@Param("from_date")String fromDate, @Param("to_date")String toDate);

вы не можете вернуть список классов pojo из базы данных. Он возвращает список классов сущностей. Использовать общедоступный список, а не общедоступный список

public List<Sale> getSaleReportByDate(@Param("from_date")String fromDate, @Param("to_date")String toDate);

@Repository
public interface SaleRepository extends JpaRepository<**Sale**, Integer>

вам нужно сопоставить список классов сущностей со списком классов POJO.

Сопоставление списка классов Entity со списком классов pojo: Поскольку есть еще много способов добиться этого Самое простое решение - перебрать класс сущности и установить атрибут сущности в атрибут pojo:

Я не предлагаю использовать конструктор, потому что иногда вам может понадобиться установить только несколько полей, а не все поля класса POJO.

Arraylist<SaleReport> sr = new Arraylist<SaleReport>();
ArrayList<Sale> saleEntityList= saleRepository.getSaleReportByDate(fromDate,toDate);
for(Sale  s : saleEntityList){
    saleReport = new SaleReport();
    saleReport.setDate(s.getDate);
    //same for all attributes
    sr.add(saleReport);
} 
return sr;

Здесь sr - ваш список POJO.

Другие вопросы по теме