spring:如何使用crudepository返回默认情况下实体的连接引用的所有对象

lmyy7pcs  于 2021-07-26  发布在  Java
关注(0)|答案(3)|浏览(230)

我有一张产品表

@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;

}

和一个粗糙的仓库

public interface ProductRepository extends PagingAndSortingRepository<Product, Integer> {

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

}

默认情况下,当我调用endpoint/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对象产品中的默认端点/产品来获取相关对象(catefory、manufacturer?
谢谢

n1bvdmb6

n1bvdmb61#

如果我理解正确,您应该在@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;
ukxgm1gy

ukxgm1gy2#

您可能需要使用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 ).

lb3vh1jj

lb3vh1jj3#

使用spring数据rest是不可能的
你的问题不太清楚,但据我所见,我想你用 Spring Data Rest 公开你的数据。
正如我在回答中所说的 Spring Data REST 使用 Spring HATEOAS 为spring数据存储库管理的实体自动公开资源,并利用超媒体特性进行分页、链接实体等。
问题是,hateoas背后的一个主要概念是发现机制。这意味着使用hateoas api,您将不可能对资源进行“懒散的解释”,这与hateoas的理念背道而驰。
这就是为什么我认为如果你真的想要相关的对象,你应该避免 Spring Data Rest ,它不适合你的需要。
相反,您可以创建自己的控制器。你会失去那个 Spring Data Rest 提供已为每个实体实现的crud操作。但是,您的数据将具有更大的灵活性,并且能够使用json响应中相关的实体公开数据。

相关问题