如何将多对一实体保存到数据库



在这个春季启动应用程序中,我有一个从CartItemone-to-many映射,其中序列化周期是通过忽略Item的序列化中的Cart来解决的。 (因此,Item中的Cart字段带有@JsonBackReference公告)

Spring 引导成功初始化数据库,以便 GET-ing 所有Carts 给出 json

[
{
"id": 1, <-- cart 1
"items": [
{
"id": 0, <-- item 0
"itemName": "tooth brush"
},
{
"id": 1,
"itemName": "shampoo"
}
]
},
{
"id": 2,
"items": [
{
"id": 2,
"itemName": "body wash"
}
]
},
{
"id": 3,
"items": []
}
]

但是,当我想向现有Cart添加Item时,新Item将另存为null

@PostMapping("carts/{cartId}")
public Cart addItemToCart(@PathVariable("cartId") long cartId, @RequestBody Item item)
{
LOG.info("Trying to add ITEM: id={}, name={}, cart={} to CART: {}", item.getId(), item.getItemName(), item.getCart(), cartId);
Cart cart = dao.getById(cartId);
LOG.info("I) CART: id={}, items={}", cart.getId(),cart.getItems().stream().map(i -> i.getItemName()).collect(Collectors.toList()));
// also tried at this location: item.setCart(cart);
cart.getItems().add(item);
LOG.info("II) CART: id={}, items={}", cart.getId(),cart.getItems().stream().map(i -> i.getItemName()).collect(Collectors.toList()));
Cart res = dao.save(cart); // HERE CART SAVES NEW ITEM AS NULL
LOG.info("III) CART: id={}, items={}", res.getId(),res.getItems().stream().map(i -> i.getItemName()).collect(Collectors.toList()));
Cart resCheck = dao.getById(res.getId());
LOG.info("IV) CART: id={}, items={}", resCheck.getId(),resCheck.getItems().stream().map(i -> i.getItemName()).collect(Collectors.toList()));
return res;
}

假设我想添加一个名称为"啤酒"的Item,以Cartcartid=1。在我看来,我只需要 json 中的itemName,因为Cart字段被忽略(@JsonBackReference),并且itemid是自动生成的。

所以,发布

{
"itemName":"beer"
}

localhost:9200/demo/api/carts/1给出日志(与上面的代码比较)

Trying to add ITEM: id=0, name=beer, cart=null to CART: 1
I) CART: id=1, items=[tooth brush, shampoo]
II) CART: id=1, items=[tooth brush, beer, shampoo]
III) CART: id=1, items=[null, tooth brush, shampoo] <-- beer itemName is null after dao.save()
IV) CART: id=1, items=[null, tooth brush, shampoo]

这并不奇怪,因为Carts 和Items 都连接在一起cartid但是当序列化Item忽略任何Cart信息时,啤酒Item应该从哪里获得cartid!如果我发布什么也不起作用

{
"itemName":"beer",
"cart":{
"id":1,
"items":[]
}
}

这也将新项目保存为 null。

真正想避免的是切换JsonBackReferenceJsonManagedReference

如何仍可将Items 添加到Carts?

以下是实体类

@Entity
@Table(name="items")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class Item
{
@Id
@GenericGenerator(name="itemIdGen" , strategy="increment")
@GeneratedValue(generator="itemIdGen")
@Column(name = "itemid", nullable=false)
private long id;
@Column(name="itemname")
private String itemName;
@ManyToOne
@JoinColumn(name = "cartid", nullable=false)
@JsonBackReference
private Cart cart;
/*...*/
}
@Entity
@Table(name="carts")
public class Cart 
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "cartid", nullable=false)
private long id;
@Column(name="items")
@OneToMany(mappedBy = "cart")
@JsonManagedReference
private Set<Item> items;
/*..*/
}

感谢您的帮助

PS:如果你想克隆一开始链接的仓库,你还需要运行尤里卡服务器并克隆demo-commons项目。

> 解决方案是忘记在Item中引用整个Cart对象,而只保留cartid(合并)

@Entity
@Table(name="carts")
public class Cart 
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "cartid", nullable=false)
private long id;
//  @Column(name="items")
//    @OneToMany(mappedBy = "cart")
//  @JsonManagedReference
//    private Set<Item> items;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name="cartid", referencedColumnName="cartid")
private Set<Item> items;
/*..*/
}
@Entity
@Table(name="items")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class Item
{
@Id
@GenericGenerator(name="itemIdGen" , strategy="increment")
@GeneratedValue(generator="itemIdGen")
@Column(name = "itemid", nullable=false)
private long id;
@Column(name="itemname")
private String itemName;
//    @ManyToOne
//    @JoinColumn(name = "cartid", nullable=false)
//    @JsonBackReference
//    private Cart cart;
@Column(name="cartid")
private Long cartId;
/*..*/
}

现在我可以愉快地发布Item

{
"itemName":"beer",
"cartid":1
}

相关内容

  • 没有找到相关文章

最新更新