簡體   English   中英

Spring:默認情況下,如何使用 CrudRepository 返回具有實體連接引用的所有對象

[英]Spring: How to return all objects with joined references of an entity by default with CrudRepository

我有一個產品表

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Product extends AuditModel {

    @Id
    @SequenceGenerator(name="optimized-sequence",sequenceName = "seq_product")
    private Integer id;
    private String sku;
    private String description;
    @NotNull
    private String name;

    *** 
    ***
    ***   

    @ManyToOne(optional = true)
    @JoinColumn(name = "category_id")
    @OnDelete(action = OnDeleteAction.NO_ACTION)
    private Category category;

    @ManyToOne(optional = true)
    @JoinColumn(name = "manufacturer_id")
    @OnDelete(action = OnDeleteAction.NO_ACTION)
    private Manufacturer manufacturer;

    @OneToMany(mappedBy = "product")
    private List<OrderProduct> orderProducts;

}

還有一個 CrudRepository

public interface ProductRepository extends PagingAndSortingRepository<Product, Integer> {

    Product findFirstBydescription(@Param("description")String description);

}

當我默認調用端點 /products 時,我會得到一個這樣的所有產品列表

{
  "_embedded" : {
    "products" : [ {
      "createdAt" : "2019-11-15T08:56:23.393+0000",
      "updatedAt" : "2019-11-15T08:56:23.393+0000",
      "id" : 802,
      "sku" : null,
      "name" : " product 1",
      "description" : "description one",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/api/products/802"
        },
        "product" : {
          "href" : "http://localhost:8080/api/products/802{?projection}",
          "templated" : true
        },
        "manufacturer" : {
          "href" : "http://localhost:8080/api/products/802/manufacturer"
        },
        "orderProducts" : {
          "href" : "http://localhost:8080/api/products/802/orderProducts"
        },
        "category" : {
          "href" : "http://localhost:8080/api/products/802/category"
        }
      }
    }, .......

我怎樣才能在 json object 產品中調用默認端點 /products 也獲得相關對象(Catefory,制造商......)?

謝謝

如果我理解正確,您應該在 @ManyToOne 或 @OneToOne 注釋中使用FetchType.EAGER策略來從數據庫中獲取所有相關數據。

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "category_id")
@OnDelete(action = OnDeleteAction.NO_ACTION)
private Category category;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "manufacturer_id")
@OnDelete(action = OnDeleteAction.NO_ACTION)
private Manufacturer manufacturer;

@OneToMany(mappedBy = "product", fetch = FetchType.EAGER)
private List<OrderProduct> orderProducts;

您可能希望使用FETCH JOIN重寫您的查詢:

@Query("SELECT p FROM Product p JOIN FETCH p.category JOIN FETCH p.manufacturer JOIN FETCH p.orderProducts WHERE p.description = :description")
Product findFirstByDescription(@Param("description") String description);

它將急切地獲取產品的關聯。

請注意,在這種情況下,您應該延遲獲取關聯(即將關聯注釋的fetch參數設置為EAGER )。

這是不可能的 Spring 數據 Rest

您的問題不是很清楚,但據我所知,我假設您使用Spring Data Rest來公開您的數據。

正如在這個答案中所說

Spring Data REST uses Spring HATEOAS to automatically expose resources for entities managed by Spring Data repositories and leverages hypermedia aspects to do pagination, link entities etc.

問題是,HATEOAS 背后的主要概念之一是發現機制 這意味着使用 HATEOAS API,您將無法對您的資源進行“懶惰的展示”,這違反了 HATEOAS 的理念。

這就是為什么我認為如果你真的想要相關的對象,你應該避免Spring Data Rest ,它不符合你的需要。

相反,您可以制作自己的控制器。 您將失去Spring Data Rest提供的設施,並且已經為每個實體實施了CRUD操作。 但是您將擁有更大的數據靈活性,並且能夠使用 JSON 響應中相關的實體公開數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM