Spring boot 3 Вопросы: Почему нельзя вызвать API с помощью Postman и API вызова Frontend, а затем получить пустой массив? - PullRequest
0 голосов
/ 08 февраля 2020

Я создал API, он называется функцией поиска магазинов. .

MySql Сценарий

Когда я использую это SQL Сценарий запускается в MySql. Будет показан действительный результат

SET @productName = null;
SET @BranchName = null;
SET @minPrice = 0;
SET @maxPrice = 10000;
SET @quantity = 1000;

SELECT * FROM stores s 
INNER JOIN products p 
ON p.id = s.product_id 
INNER JOIN branches b 
ON b.id = s.branch_id 
WHERE (p.name LIKE CONCAT('%', @productName , '%') OR @productName IS NULL) 
  AND (b.name LIKE  CONCAT('%', @branchName , '%')  OR @branchName IS NULL) 
  AND (@minPrice <= p.price AND p.price <= @maxPrice) 
  AND s.quantity <= @quantity 
ORDER BY p.name, b.name, quantity;

.

Щелкните изображение, чтобы увидеть результат MySQL

MySQL и действительное изображение результата

Журнал из StoreService. java и Hibernate

Нажмите, чтобы увидеть Почтальон перед вызовом API

Когда я вызываю его по внешнему интерфейсу, происходит вход в систему StoreService . java is ...

productName: null, minPrice: 0.0, maxPrice: 15000.0, branchName: null, 1000
Hibernate: SELECT * FROM stores s INNER JOIN products p ON p.id = s.product_id INNER JOIN branches b ON b.id = s.branch_id WHERE (p.name LIKE CONCAT('%', ? , '%') OR ? IS NULL)  AND (b.name LIKE  CONCAT('%', ? , '%')  OR ? IS NULL)  AND (? <= p.price AND p.price <= ?)  AND s.quantity <= ?  ORDER BY p.name
Stores: []

.

Журнал ошибок при вызове API почтальоном

Изображение параметров почтальона
При вызове почтальоном получите

java.lang.StackOverflowError: null
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:944) ~[mysql-connector-java-8.0.19.jar:8.0.19]
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:1003) ~[mysql-connector-java-8.0.19.jar:8.0.19]
    at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52) ~[HikariCP-3.4.2.jar:na]
    at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java) ~[HikariCP-3.4.2.jar:na]
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:57) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.getResultSet(AbstractLoadPlanBasedLoader.java:390) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeQueryStatement(AbstractLoadPlanBasedLoader.java:163) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:104) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:87) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:707) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:76) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:108) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:2145) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:589) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:264) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:585) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:149) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:458) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at com.g_able.back_g_exam.entity.Product.hashCode(Product.java:12) ~[classes/:na]
    at com.g_able.back_g_exam.entity.Store.hashCode(Store.java:13) ~[classes/:na]
    at java.util.HashMap.hash(HashMap.java:339) ~[na:1.8.0_172]
    at java.util.HashMap.put(HashMap.java:612) ~[na:1.8.0_172]
    at java.util.HashSet.add(HashSet.java:220) ~[na:1.8.0_172]
    at java.util.AbstractCollection.addAll(AbstractCollection.java:344) ~[na:1.8.0_172]
    at org.hibernate.collection.internal.PersistentSet.endRead(PersistentSet.java:355) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:239) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:224) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:198) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerImpl.endLoading(CollectionReferenceInitializerImpl.java:154) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishLoadingCollections(AbstractRowReader.java:267) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]
    at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:218) ~[hibernate-core-5.4.10.Final.jar:5.4.10.Final]

.

Мой код Springboot:

StoreController. java

@GetMapping("/api/v1/stores/advance-search")
  public List<Store> findStoresByFilter(
      @RequestParam(required = false) String productName, @RequestParam(required = false) String branchName,
      @RequestParam(required = false, defaultValue = "0") Integer minPrice,
      @RequestParam(required = false, defaultValue = "999999") Integer maxPrice,
      @RequestParam(required = false, defaultValue = "3000") Integer quantity) {

    ProductParams productParams = ProductParams.builder().name(productName).minPrice(minPrice).maxPrice(maxPrice).build();
    Branch branch = Branch.builder().name(branchName).build();

    List<Store> stores = storeService.findStoresByFilter(productParams, branch, quantity);
    System.out.println("Stores: " + stores);
    return stores;

}

.

StoreService. java

public List<Store> findStoresByFilter(ProductParams productParams, Branch branch, int quantity) {
    System.out.println("productName: " + productParams.getName() + ", minPrice: " + productParams.getMinPrice() + ", maxPrice: "
        + productParams.getMaxPrice() + ", branchName: " + branch.getName() + ", " + quantity);
    return storeRepository.searchStoresByFilter(productParams.getName(), branch.getName(),
        productParams.getMinPrice(), productParams.getMaxPrice(), quantity);
}

.

StoreRepository. java

@Query(nativeQuery = true,
      value = "SELECT * " +
          "FROM stores s " +
          "INNER JOIN products p " +
          "ON p.id = s.product_id " +
          "INNER JOIN branches b " +
          "ON b.id = s.branch_id " +
          "WHERE (p.name LIKE CONCAT('%', :productName , '%') OR :productName IS NULL) " +
          " AND (b.name LIKE  CONCAT('%', :branchName , '%')  OR :branchName IS NULL) " +
          " AND (:minPrice <= p.price AND p.price <= :maxPrice) " +
          " AND s.quantity <= :quantity " +
          " ORDER BY p.name")
  List<Store> searchStoresByFilter(@Param("productName") String productName, @Param("branchName") String branchName,
                                 @Param("minPrice") double minPrice, @Param("maxPrice") double maxPrice, @Param("quantity") int quantity);

Примечание:

В моих POJO меня отмечают, что у них есть предупреждения о @ Table и @ JoinColumn из javax.persistence package

Cannot resolve table 'table_name' в @ Table и Cannot resolve column 'product_id'
Cannot resolve column 'branch_id' in @ JoinC olumn

Store. java (Pojo)

Product. java (Pojo)

Branch. java (Pojo)

Я хочу знать root причины

  1. Почему я не могу получить действительный результат при вызове API из внешнего интерфейса?
  2. Почему я не могу вызвать API из Почтальона?
  3. Почему аннотация из javax.persistenct не может разрешить table_name и column_name ?

Наконец, мне нужны решения для решения этих проблем

Большое спасибо за вашу помощь

Ответы [ 2 ]

0 голосов
/ 09 февраля 2020

Я уже нашел, как исправить, что Postman не может завершить sh этот API и Frontend получают пустой массив.

Я просто добавляю @ToString(exclude = "stores") и @EqualsAndHashCode(exclude = "stores") в сущность, которая имеет ассоциацию как Многие to Many .

Текущий код в сущностях:

Product. java

@Data
@ToString(exclude = "stores")
@EqualsAndHashCode(exclude = "stores")
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "products")
@Builder(toBuilder = true)
public class Product {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Integer id;

  @Column(nullable = false, length = 50)
  private String name;

  private String detail;

  private double price;

  @JsonIgnore
  @OneToMany(mappedBy = "product")
  private Set<Store> stores;

}

Branch. java

@Data
@ToString(exclude = "stores")
@EqualsAndHashCode(exclude = "stores")
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "branches")
@Builder(toBuilder = true)
public class Branch {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Integer id;

  @Column(nullable = false, length = 60)
  private String name;

  @JsonIgnore
  @OneToMany(mappedBy = "branch")
  private Set<Store> stores;
}

Но я пока не понимаю, почему это ошибки. Не могли бы вы объяснить это?

0 голосов
/ 08 февраля 2020

Я отмечен в моих классах сущностей, что у них есть предупреждения о @Table от javax.persistence. Не удается разрешить таблицу 'table_name' в @Table, и не удается разрешить столбец 'product_id'. Не удается разрешить столбец 'branch_id' в @JoinColumn

По этой причине hibernate не может на самом деле отобразить таблицу, вам нужно исправить отображение прежде, чем что-либо еще, чтобы hibernate знал, какую таблицу использовать. В настоящее время он ищет 'table_name' в sql, который не является вашим магазином или таблицей продуктов. Мы не знаем, правильны ли ваши сопоставления, поскольку код класса сущностей здесь не передается, но вполне вероятно, что у аннотации или xml файла неверное имя сопоставления из самой ошибки, что в конечном итоге приводит к сбою всего запроса.

Редактировать : любезно проверьте, включены ли эти библиотеки в ваш classpath: hibernate-annotations.jar lib / hibernate-comons-annotations.jar lib / ejb3-persistence.jar

Также я бы предложил вам использовать язык запросов hibernate вместо собственных запросов, поскольку они гораздо более расширяемы, когда вы хотите переключить базовую базу данных.

Root причина в том, что hibernate - это уровень абстракции базы данных, известный как DBAL, вся цель этой библиотеки - создавать запросы от имени ваш код и выполнить их. Вы пытаетесь использовать его как нативную оболочку sql, и запросы sql дадут результат гибернации, но поскольку отображение неверно, оно не может анализировать и хранить данные в ваших сущностях, хотя в некоторых случаях это полезно, сама гибернация предоставляет гораздо больше Надежные функции, такие как отложенная загрузка, отношения сущностей и другие.

Вы можете прочитать полную документацию здесь, чтобы использовать такие функции. Руководство по началу работы

Ссылка на язык запросов Hibernate

...