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

时间:2018-03-07 17:34:50

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

this spring boot app中,我有一个从one-to-manyCart的{​​{1}}映射,其中序列化周期通过忽略Item中的Cart来解决序列化。 (因此Item中的Cart字段带有Item annocation)

Spring启动成功初始化数据库,以便GET-ing所有@JsonBackReference s给出json

Cart

但是,当我想向现有[ { "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": [] } ] 添加Item时,新Cart会另存为Item

null

说我要添加名为&#34;啤酒&#34;的@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转至Cart。在我看来,我只需要json中的cartid=1因为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] Cart已加入Item,但啤酒cartid应该从哪里获得Item序列化cartid时忽略任何Item信息!如果我发布

,什么也行不通
Cart

还将新项目保存为null。

真正想要避免的是切换{ "itemName":"beer", "cart":{ "id":1, "items":[] } } JsonBackReference

如何将JsonManagedReference添加到Item s?

以下是实体类

Cart

感谢您的帮助

P.S。:如果你想克隆在开头链接的repo,你还需要运行eureka server并克隆demo-commons项目。

1 个答案:

答案 0 :(得分:1)

解决方案是忘记引用Cart中的整个Item对象,但只保留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
}