0

我有一个产品表

@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 对象产品中调用默认端点 /products 来获取相关对象(Catefory、Manufacturer ...)?

谢谢

4

3 回答 3

0

如果我理解正确,您应该 在 @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;
于 2019-11-15T14:06:44.370 回答
0

Spring Data Rest 不可能

你的问题不是很清楚,但据我所知,我假设你用它Spring Data Rest来公开你的数据。

正如在这个答案中所说

Spring Data REST用于Spring HATEOAS为 Spring Data 存储库管理的实体自动公开资源,并利用超媒体方面进行分页、链接实体等。

问题是,HATEOAS 背后的主要概念之一是发现机制。这意味着使用 HATEOAS API,您将无法对您的资源进行“懒惰的展示”,这违反了 HATEOAS 的理念。

这就是为什么我认为如果你真的想要相关的对象,你应该避免Spring Data Rest,它不符合你的需要。

相反,您可以制作自己的控制器。您将失去提供的设施,并且已经为每个实体实施Spring Data RestCRUD操作。但是您将拥有更大的数据灵活性,并且能够使用 JSON 响应中相关的实体公开数据。

于 2019-11-15T19:46:25.417 回答
0

您可能希望使用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)。

于 2019-11-15T14:18:10.753 回答