繁体   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