Spring 数据存储库不会以多对多关系保存数据

Posted

技术标签:

【中文标题】Spring 数据存储库不会以多对多关系保存数据【英文标题】:Spring data repository does not save data in an Many to Many relation 【发布时间】:2020-11-28 09:23:39 【问题描述】:

我正在创建一个允许我管理发票的数据模型。我遇到的问题是当我尝试通过@POST 使用服务时。一切都是正确的,即使我在数据库中验证并且没有外键 invoice_id 的记录

此处出错:

@Entity
@Table(name = "invoice")
data class Invoice (

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        val id: Int? = 0,

        val createdAt: LocalDateTime? = LocalDateTime.now(),
        val updatedAt: LocalDateTime? = LocalDateTime.now(),

        val nombre: String? = "",
        val direccion: String? = "",
        val telefono: String? = "",

        var order_total : Int? = null,

        @OneToMany(mappedBy = "invoice", cascade = [CascadeType.ALL])
        @JsonManagedReference
        val invoiceItems: List<InvoiceItem>? = mutableListOf()

)

@Entity
@Table(name = "item")
data class Item(
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        val id: Long? = null,
        val name: String? = null,
        val description: String? = null,
        val price: Int? = null,
        val img_url: String? = null,
        val createdAt: LocalDateTime? = LocalDateTime.now(),
        val updatedAt: LocalDateTime? = LocalDateTime.now(),

        @OneToMany(mappedBy = "item", cascade = [CascadeType.ALL])
        @JsonBackReference
        val items: List<InvoiceItem>? = mutableListOf()

        )
@Entity
@Table(name = "invoice_item")
data class InvoiceItem(

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        val id: Int? = 0,

        val quantitiy: Int? = 0,

        @ManyToOne
        @JoinColumn (name = "invoice_id")
        @JsonIgnore
        val invoice: Invoice? = null,

        @ManyToOne
        @JoinColumn
        val item: Item? = null

)
HTTP/1.1 200 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Sat, 08 Aug 2020 04:35:13 GMT
Keep-Alive: timeout=60
Connection: keep-alive


  "id": 5,
  "createdAt": "2020-08-07T23:35:13.2283331",
  "updatedAt": "2020-08-07T23:35:13.2283331",
  "nombre": "Z",
  "direccion": "Bosquera",
  "telefono": "12000",
  "order_total": 1000,
  "invoiceItems": [
    
      "id": 7,
      "quantitiy": 10,
      "item": 
        "id": 1,
        "name": "Costilla de Cerdo Ahumadas Ranchera",
        "description": "Costilla Ahumada, 500 Gramo(s).",
        "price": 30700,
        "img_url": "https://images.rappi.com/products/443434-1594427331970.png",
        "createdAt": "2020-08-07T23:28:03",
        "updatedAt": "2020-08-07T23:28:03"
      
    ,
    
      "id": 8,
      "quantitiy": 10,
      "item": 
        "id": 2,
        "name": "Hamburguesa Preasada Zenu X 400G",
        "description": "Hamburguesa Preasada Zenu X 400G. 25% Reducido En Sodio, Buena Fuente De Proteína PLU: 802599",
        "price": 12350,
        "img_url": "https://images.rappi.com/products/802599-1594427485528.png",
        "createdAt": "2020-08-07T23:28:03",
        "updatedAt": "2020-08-07T23:28:03"
      
    
  ]


非常感谢您的帮助,我敢于发布,因为我已经尝试了解问题所在但我找不到它

【问题讨论】:

您可以将您的源代码与此处的示例进行比较,它具有所有类型的数据库关系:github.com/dineshbhagat/spring-boot-web-jpa 我刚查了一下,但找不到这种类型的 ManyToMany。 你能告诉我你是如何为你的帖子请求编码的吗? 我有所有的信息,发布请求,发布响应,以及所有库存物品 -> pastebin.com/v15UKH3K 我的意思是您的帖子请求的控制器/服务 【参考方案1】:

对于双向关系,需要同步两端,这意味着您必须设置每个 InvoiceItem 的发票字段,然后设置外键。

fun addOrder(invoice: Invoice): ResponseEntity<Invoice> 
   invoice.invoiceItems.forEach  it -> it.invoice= invoice
   ResponseEntity.ok(parentRepository.save(invoice))

【讨论】:

非常感谢,显然它已经奏效了,但是虽然我有疑问,但确实有必要在foreach中分配每个,hibernate会自动处理关联这个吗? 外键必须两端同步,休眠不会自动进行【参考方案2】:

你检查过你的 JSON 反序列化是否正确吗?如果没有@JsonManagedReference / @JsonBackReference,InvoiceItem 中可能不会设置双向关系

@Entity
@Table(name = "invoice_item")
data class InvoiceItem(

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Int? = 0,

    val quantitiy: Int? = 0,

    @ManyToOne
    @JoinColumn (name = "invoice_id")
    @JsonBackReference
    val invoice: Invoice? = null,

    @ManyToOne
    @JoinColumn
    @JsonManagedReference
    val item: Item? = null

)

【讨论】:

我刚刚发送了一个Invoice类型的对象,答案是这个pastebin.com/tsivFETM我再次检查了invoice_id关系,它们仍然是空的,它没有关联关系 我有所有的信息,发布请求,发布响应,以及所有库存物品 -> pastebin.com/v15UKH3K

以上是关于Spring 数据存储库不会以多对多关系保存数据的主要内容,如果未能解决你的问题,请参考以下文章

如何创建如何在 typeorm 中创建多对多关系,[NestJS]

通过链接到SQL Server数据库的MS Access以多对多关系插入数据(中间表)

实体框架使用 Codefirst、通用存储库、工作单元模式保存多对多关系

在 MS Access 中,如何以多对多关系列出记录,以使所列出的表中的记录不重复?

以多对多关系对相关集进行排序

*** 错误设置多对多关系 Spring JPA