简体   繁体   中英

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

I have a product table

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

}

And a CrudRepository

public interface ProductRepository extends PagingAndSortingRepository<Product, Integer> {

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

}

when i call the endpoint /products by default I get a list of all products like this

{
  "_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"
        }
      }
    }, .......

How can I get, calling the default endpoint /products, inside the json object product the related objects too (Catefory, Manufacturer...)?

Thanks

If am I understand you correctly, you should use FetchType.EAGER strategy inside the @ManyToOne or @OneToOne annotations for fetching all related data from the database.

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

You may want to rewrite your query using 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);

It will fetch Product's associations eagerly.

Note that in this case you should make your associations lazily fetched (ie set fetch parameter of association annotations to EAGER ).

It's not possible with Spring Data Rest

It's not very clear in your question, but from what I see, I assume you use Spring Data Rest to expose your data.

As said in this answer

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.

The thing is, one of the main concepts behind HATEOAS is the discovery mechanism . It means that with an HATEOAS API, you won't have the possibility to make a "Lazy exposition" of your resources, it's against the philosophy of HATEOAS.

That's why I think if you really want related objects, you should avoid Spring Data Rest , it won't fit your needs.

Instead, you can make your own controllers. You will lose the facility that Spring Data Rest provides, with the CRUD operations already implemented for each entity. But you will have more flexibility with your data, and will be able to expose data with entities related in your JSON response.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM