首页 > 解决方案 > 如何创建所有链接在一起的 OneToOne 和 OneToMany

问题描述

我来自前端,所以这一切对我来说都是新的。我有以下实体Client, CartProduct它们之间是这样连接的:

  1. Client<=> @OneToOne<=>Cart
  2. Cart=> @OneToMany=> Product(@ManyToOneCart)

运行 mySpringDataJpaApplication在 Postgres 中正确创建了我的所有 3 个表,其中包含所有相应的列及其外键。Cart使用所有字段创建一个新的,将在 Postgres 中创建ClientCart,但不会Product创建@ManyToOne. 查询数据库将生成空字段Product

// Client
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Entity
public class Client {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int client_id;

private String name;
private String lastName;

@OneToOne(mappedBy = "client")
private Cart cart;
}


// Cart
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Entity
public class Cart {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int cart_id;

@OneToMany(mappedBy = "cart")
private List<Product> productList;


@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "fk_client_id", referencedColumnName = "client_id")
    private Client client;
}


//Product
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Entity
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int product_id;
    private String productName;
    private int price;
    private int qty;

    @ManyToOne
    @JoinColumn(name = "fk_cart_id")
    private Cart cart;
}


// CartController
@RestController
    public class CartController {

        @Autowired
        CartRepository cartRepository;

        @PostMapping("/createCart")
        public Cart createCart(@RequestBody Cart request) {
            return cartRepository.save(request);
        }
}

如前所述,发布到端点会返回一个只为和200创建的带有记录(如上所述)。发帖请求如下:ClientCart

{
  "productList": [
    {
      "productName": "mobile",
      "price": 800,
      "qty": 2
    }
  ],
  "client": {
    "name": "John",
    "lastName": "Done"
  }
}

我究竟做错了什么?为什么没有Product填充表格?(注意:只有@OneToMany@ManyToOne之间CartProduct我可以同时填充它们,但是当Client混合在一起时,我遇到了上面描述的问题)

标签: javaspringhibernatespring-data-jpa

解决方案


拥有实体的概念是您所缺少的。

Cart您拥有的实体中:

@OneToMany(mappedBy = "cart")
private List<Product> productList;

这表示该Product实体拥有该关系。只有拥有关系的实体才能保持关系。这意味着 aProduct可以坚持 aCart但反之则不行。总之,你要坚持一个Product自己。所以,保存购物车,然后在产品中设置购物车,然后保存产品。

如果您没有它,那么它@ManyToOne本身就决定了相同的行动方案。

@ManyToOne
@JoinColumn(name = "fk_cart_id")
private Cart cart;

应被productList视为仅查询字段。

请注意,您可以玩带有Cascade注释的游戏,Cart但我不建议这样做。这是一个有点复杂和令人烦恼的注释。与其Repository在您的Controller层中创建一个层,不如创建一个@Service层并将持久化、检索和其他业务逻辑放入其中,并将其包含在您的控制器中。标准模式。

然后为您的服务层编写 junit/mockito 测试用例。

编辑:为了清楚起见, aProduct不能持久化 a Cart,而是必须有一个先前持久化Cart的设置到购物车字段。Cart对实体没有这样的要求。


推荐阅读