jpa 如何在spring Boot 中只发送body请求中主嵌套对象的ID

2skhul33  于 2023-02-16  发布在  Spring
关注(0)|答案(3)|浏览(145)

我正在使用Spring Boot和JPA为商家创建电子商务。在创建订单服务时遇到了一个问题。我只想在请求正文中传递嵌套对象的ID,而不是发送完整的嵌套对象,因为其大小将非常大。
这是我的代码。商家可以做许多订单

    • 订单**
@Entity
@Table(name = "Orders")
@XmlRootElement
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Order extends BasicModelWithIDInt {

    @Basic(optional = false)
    @Column(name = "Quantity")
    private Integer quantity;

    @Basic(optional = false)
    @Size(min = 1, max = 150)

    @Column(name = "Notes")
    private String notes;

    @JoinColumn(name = "ProductID", referencedColumnName = "ID")
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JsonIgnoreProperties
    private Product productID;

    @JoinColumn(name = "MerchantID", referencedColumnName = "ID")
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private Merchent merchent;

    @JoinColumn(name = "OrderSatusID", referencedColumnName = "ID")
    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    private OrderStatus orderStatus;

      // Getters and Setters
}
    • 订单持有人**
public class OrderHolder {

    @NotNull
    private Order order;

    public Order getOrder() {
        return order;
    }

    public void setOrder(Order order) {
        this.order = order;
    }
}
    • 订单回购**
public interface OrderRepo extends JpaRepository<Order, Integer> {
}
    • 订单管理员**
@RestController
@RequestMapping(value = "order", produces = MediaType.APPLICATION_JSON_VALUE)
public class OrderRestController extends BasicController<OrderHolder>{

    @Autowired
    private OrderRepo orderRepo;

 

    @PostMapping("create")
    public ResponseEntity<?> create(@RequestBody @Valid OrderHolder orderHolder, Principal principal) throws GeneralException {
        log.debug( "create order {} requested", orderHolder.toString());
        Order order = new Order();
        order = orderHolder.getOrder();
        System.out.println("###############"+order);
        try {
            order = orderRepo.save(order);
            log.info( "Order {} has been created", order );
        } catch (Exception e) {
            log.error( "Error creating Order:  ", e );
            e.printStackTrace();
            throw new GeneralException( Errors.ORDER_CREATION_FAILURE, e.toString() );
        }
        return ResponseEntity.ok( order );
    }

}

我需要请求身体看起来像下面,而不是包括完整的商人和产品内的请求对象。

bprjcwpo

bprjcwpo1#

您可以使用JsonView只返回产品和商家的ID

public class OrderView {}

...

public class Product{

         @Id
         @JsonView(OrderView.class)
         private Integer id

         private String otherFieldWithoutJsonView
...
        }

然后在你的控制器里

@PostMapping("create")
@JsonView(OrderView.class) // this will return the product object with one field (id)
    public ResponseEntity<?> create(@RequestBody @Valid OrderHolder orderHolder, Principal principal) throws GeneralException {
        ...
    }

希望这能帮到你

efzxgjgh

efzxgjgh2#

只是有一个单独的合同类。

public class OrderContract {
    private int merchantID;
    private String notes;
    ....
//getter, setters
}

public class OrderHolder {

   @NotNull
   private OrderContract orderContract;

   public OrderContract getOrderContract() {
       return orderContract;
   }

   public void setOrder(OrderContract orderContract) {
       this.orderContract = orderContract;
   }
}

在调用Repository之前,将OrderContract转换为Order。

kdfy810k

kdfy810k3#

我想分享一些关于这方面的东西。我已经在网上搜索了很多,尝试了很多东西,但这里给出的解决方案很适合这种情况。
https://www.baeldung.com/jackson-deserialization
您需要通过从com.fasterxml.jackson.databind.deser.std.StdDeserializer扩展StdDeserializer来为您的模型创建一个定制的反序列化器,其中您只想传递id而不是请求中的整个对象。
我已经给出了下面的例子,为用户模型与地址对象.

User(long userId, String name, Address addressId)
Address(long addressId, String wholeAddress)

正在编写User类的反序列化程序

public class UserDeserializer extends StdDeserializer<User> { 

public User() { 
    this(null); 
} 

public User Deserializer(Class<?> vc) { 
    super(vc); 
}

@Override
public User deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
    JsonNode node = p.getCodec().readTree(p);
    long id = 0;
    
    long addressId = (Long) ((IntNode) node.get("addressId")).numberValue().longValue();
    return new User(id, name, new Address(addressId, null)
    
}

现在你必须使用

@JsonDeserialize(using = UserDeserializer.class)
public Class User {

...

}

POST请求
自定义反序列化之前

{
  "name" : "Ravi",
  "addressId" : { "id" : 1} 
}

自定义反序列化之后

{
  "name" : "Ravi",
  "addressId" : 1
}

另外,在调用GET/user/:id时,您将获得整个对象,如

{
  "name" : "Ravi",
  "addressId" : { "id" : 1, "wholeAddress" : "Some address"} 
}

相关问题