我有一个对象,其中包含其他我似乎无法正确更新的对象的列表。我可以用对象列表(ProductItemQuantity)创建对象(产品),没有问题。我也可以使用对象列表进行PUT,但是我所做的所有操作都会创建一个新的对象列表。我希望我提供的对象列表得到更新,而不是每次我放置父对象时都要创建一个新列表。
如果我向ProductItemQuantity添加ID,则会出现异常:
30,000
这是我的课程:
Product.java
detached entity passed to persist
ProductItemQuantity.java
@Entity
public class Product {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@ManyToOne
private Organization org;
private String barCode;
private String name;
@ManyToOne(cascade=CascadeType.MERGE)
private Status status;
@ManyToMany(cascade=CascadeType.MERGE)
private List<Fee> fees;
@ManyToMany(cascade=CascadeType.ALL)
private List<Note> notes;
@ManyToMany(cascade=CascadeType.ALL)
private List<ProductItemQuantity> productItems;
private Integer stock;
private BigDecimal msrp;
@CreationTimestamp
private LocalDateTime createdOn;
@UpdateTimestamp
private LocalDateTime updatedOn;
// Getter & Setters
ProductItem.java
@Entity
public class ProductItemQuantity {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private Integer count;
@ManyToOne
private ProductItem productItem;
@CreationTimestamp
private LocalDateTime createdOn;
@UpdateTimestamp
private LocalDateTime updatedOn;
// Getters / setters
ProductController.java
@Entity
public class ProductItem {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@ManyToOne
private Organization org;
@ManyToOne
private Supplier supplier;
private String barCode;
private String description;
private String name;
private Integer stock;
private Integer caseQty;
private BigDecimal caseCost;
@ManyToMany(cascade=CascadeType.ALL)
private List<Note> notes;
@CreationTimestamp
private LocalDateTime createdOn;
@UpdateTimestamp
private LocalDateTime updatedOn;
有效的CRUD PUT请求:http://localhost:8080/product/1
@PutMapping("/{id}")
public Product update(@RequestBody Product product, @PathVariable long id) {
Product savedProduct = productService.save(product);
return savedProduct;
}
残破的CRUD PUT请求:http://localhost:8080/product/1
{
"barcode":"12347163",
"name":"Product 1",
"stock": 12,
"msrp": 29.99,
"org": {
"id":1
},
"status":{
"id":1
},
"productItems":[{
"count":30
},{
"count":30
}
],
"fees":[{
"id":1
},{
"id":2
}],
"notes":[{
"title":"Product Created",
"description":"Note created by user X on 12/16/2019 11:00PM"
},{
"title":"Product Updated",
"description":"Product updated stock by user X on 12/16/2019 11:00PM"
}]
}
答案 0 :(得分:1)
因为对象(OneToMany,ManyToMany)的关系仅从一个方向设置,所以您的对象已分离。为了持久化它们,您必须设置双向关系。您的关系是单向的,因为解析器(杰克逊)将创建以下对象:
Product product = new Product();
Fee fee = new Fee();
fee.setId(1);
product.setFees(Arrays.asList(fee));
在双向关系中,必须设置双方:
product.getFees().forEach(fee-> fee.getProducts().add(product));
因为将持久性对象也处理关系,所以最好将持久性对象与控制器对象分开。
根据我的经验,如果要使用GeneratedValue,首先必须从数据库中选择实体,然后再对其进行修改。如果您希望休眠生成一个新对象并在其上设置ID,则没有太大意义。
因此,您可能需要先进行选择:
列出费用= //在产品费用列表中选择所有ID为ID的费用
及之后:
product.setFees(fees);
fees.forEach(fee -> fee.getProducts().add(product));
您的方法是PUT,因此您不应直接保存产品对象(它将在数据库中创建一个新条目)。
@PutMapping("/{id}")
public Product update(@RequestBody Product product, @PathVariable long id) {
Optional<Product> originalProductOptional = productRepository.findById(id);
// you should add a check here : if originalProduct is not found, return 404
Product originalProduct = originalProductOptional.get();
originalProduct.setName(product.getName());
// here update all fields and relations
productRepository.save(originalProduct);
return originalProduct;
}
答案 1 :(得分:0)
答案是将属性更新为此:
Future<void> init(String appId,
{Map<OSiOSSettings, dynamic> iOSSettings}) async {
_onesignalLog(OSLogLevel.verbose,
"Initializing the OneSignal Flutter SDK ($sdkVersion)");
var finalSettings = _processSettings(iOSSettings);
await _channel.invokeMethod(
'OneSignal#init', {'appId': appId, 'settings': finalSettings});
}
然后在推杆中手动设置
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
private List<ProductItemQuantity> productItemQuantities;