【问题标题】:How To Insert Data with Spring Data JPA Relationships如何使用 Spring Data JPA 关系插入数据
【发布时间】:2021-01-01 09:03:56
【问题描述】:

希望这是一个简单的问题,但我对 JPA 还很陌生,很难确定如何格式化发送到 Spring API 的 JSON POST 请求正文。我有两个实体 Product 和 Barcode 具有以下关系:

  • 一个产品可以有多个指向它的条形码 (OneToMany)
  • 一个条形码只能指向一个产品 (OneToOne)

关系由条形码表中的 product_id 列定义。

条形码实体中的关系定义:

@OneToOne // one barcode relates to one product
private ProductEntity product;

Product中的关系定义:

@OneToMany(cascade = CascadeType.ALL)
private List<BarcodeEntity> barcodes = new ArrayList<>();

我的问题是,如何执行 JSON POST 请求来插入与数据库中已有产品相关的条形码?我需要传递整个 Product 实体还是有办法只传递 product_id ?

当产品已经存在时,我想如何创建一个新的条形码条目:

{ 
  "barcode": "string",
  "barcodeStatus": "string",
  "codeStandard": "string",
  "product": 1,
  "title": "string",
  "unitQuantity": 0
}

不必执行以下操作,我相信这会导致错误,因为产品已经存在:

{ 
  "barcode": "string",
  "barcodeStatus": "string",
  "codeStandard": "string",
  "product": {
     productInfo: "...",
     ....,
  },
  "title": "string",
  "unitQuantity": 0
}

本质上,我试图弄清楚如何插入一个新实体并定义它与数据库中已经存在的另一个实体的关系。我确定我已经把它复杂化了。

产品控制器中的端点:

@PostMapping(produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
public ProductRest createProduct(@Valid @RequestBody ProductRequestModel productDetails) throws Exception {
    ProductRest returnValue = new ProductRest();

    ModelMapper modelMapper = new ModelMapper();
    ProductDto productDto = modelMapper.map(productDetails, ProductDto.class);

    ProductDto createdProduct = productService.createProduct(productDto);
    returnValue = modelMapper.map(createdProduct, ProductRest.class);

    return returnValue;
}

产品服务文件中的createProduct方法:

public ProductDto createProduct(ProductDto product) {
    if (productRepo.findByTitle(product.getTitle()) != null)
        throw new ServiceException("Record with matching title already exists");

    // Set product id for each barcode
    for (int i = 0; i < product.getBarcodes().size(); i++) {
        ProductBarcodeDto barcode = product.getBarcodes().get(i);
        barcode.setProduct(product); 
        product.getBarcodes().set(i, barcode);
    }

    ModelMapper modelMapper = new ModelMapper();
    ProductEntity productEntity = modelMapper.map(product, ProductEntity.class);

    ProductEntity storedProductDetails = productRepo.save(productEntity); 

    ProductDto returnValue = modelMapper.map(storedProductDetails, ProductDto.class);
    return returnValue;
}

ProductDto 中的字段(定义 getter/setter 和空构造函数;只是未显示):

public class ProductDto {

private long id;
private List<BarcodeDto> barcodes;
private String title;
private String description;
private String SKU;
private ProductVariationDto variation;
private double cost;
private double retailPrice;
private LocalDate launchDate;
private LocalDate discontinueDate;
private String discontinueReason;
private String salesChannel;
private LabelDto label;
private int secondaryStockLevel;
private int primaryStockLevel;
private LocalDateTime modifiedDate;
private LocalDateTime createdDate;
private String productStatus;
private List<SupplierDto> suppliers;
}

我已将其设置为 ProductRequestModel 需要 BarcodeEntity。这是正确的还是我应该将其更改为只期望条形码 ID 的整数值?

在条码控制器中创建条码端点:

@PostMapping(produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
public BarcodeRest createBarcode(@Valid @RequestBody BarcodeRequestModel barcodeDetails) throws Exception {
    BarcodeRest returnValue = new BarcodeRest();

    ModelMapper modelMapper = new ModelMapper();
    BarcodeDto barcodeDto = modelMapper.map(barcodeDetails, BarcodeDto.class);

    BarcodeDto createdBarcode = barcodeService.createBarcode(barcodeDto);
    returnValue = modelMapper.map(createdBarcode, BarcodeRest.class);

    return returnValue;
}

createBarcode 方法实现:

public BarcodeDto createBarcode(BarcodeDto barcode) {
    ModelMapper modelMapper = new ModelMapper();

    if (barcodeRepo.findByBarcode(barcode.getBarcode()) != null)
        throw new ServiceException("Barcode value already exists.");

    BarcodeEntity barcodeEntity = modelMapper.map(barcode, BarcodeEntity.class);
    BarcodeEntity storedBarcode = barcodeRepo.save(barcodeEntity);

    BarcodeDto returnValue = modelMapper.map(storedBarcode, BarcodeDto.class);
    return returnValue;
}

【问题讨论】:

    标签: json spring-boot jpa spring-data-jpa


    【解决方案1】:

    首先,数据库模式映射似乎存在问题:

    一个产品:许多条码(一对多)[无问题]

    许多条码:一种产品(多对一,而不是一对一)[有问题]

    其次,是的,您可以只使用“product_id”来更新条形码。如果您将控制器代码发布一次会更好。会更容易找到任何问题。

    【讨论】:

    • 感谢您的回复。我在原始帖子中添加了用于创建产品和条形码的控制器端点代码。为什么很多条码:一个产品是个问题? ManyToOne 背后的原因是,一个产品可能有一个条形码指向该产品的 1 个单位,而另一个条形码指向该产品的 50 个单位。有没有更好的处理方法?
    猜你喜欢
    • 2021-05-20
    • 1970-01-01
    • 2018-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    • 2017-11-09
    • 1970-01-01
    相关资源
    最近更新 更多