一对多外键必须与引用的主键具有相同的列数

One-To-Many Foreign key must have same number of columns as the referenced primary key

我正在尝试实现订单和订单产品之间的一对多关联,但我总是遇到此异常:

Foreign key (FKmn6eaqdlnl33lnryjkwu09r0m:order_product_entity [order_id,product_id])) must have same number of columns as the referenced primary key (orders [id])

我知道这意味着什么,但我不确定我应该如何更改我的方案来解决它。我的设计基于本教程:Spring Java eCommerce Tutorial

除了我的代码是用 Kotlin 编写的之外,我无法区分它们。

我正在使用 Spring Boot with Spring Data JPA 和 Kotlin。

我的产品实体:

@Entity
@Table(name = "product")
data class ProductEntity(
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        var id: Long,
        @NotNull(message = "Product name is required")
        var name: String,
        var price: Double,
        var description: String

)

我的订单实体:

@Entity
@Table(name = "orders")
data class OrderEntity(
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        var id:Long,

        var dateCreated:Date,

        var status:String,

        @JsonManagedReference
        @OneToMany(cascade = arrayOf(CascadeType.ALL), mappedBy = "orderProductEntityId")
        @Valid
        val orderProducts: List<OrderProductEntity>
)

订单产品实体:

@Entity
data class OrderProductEntity(
        @EmbeddedId
        @JsonIgnore
        var orderProductEntityId: OrderProductEntityId,

        @JsonBackReference
        @ManyToOne(optional = false, fetch = FetchType.LAZY)
        var order: OrderEntity,

        @ManyToOne(optional = false, fetch = FetchType.LAZY)
        var product: ProductEntity,

        @Column(nullable = false)
        var quantity: Int = 0
)

我的复合主键:

@Embeddable
data class OrderProductEntityId(
        @Column(name = "order_id")
        var orderId: Long = 0,

        @Column(name = "product_id")
        var productId: Long = 0
) : Serializable

有什么建议吗?

我相信您正在使用 "derived identities"。尝试像这样映射 OrderProductEntity

@Entity
data class OrderProductEntity(
    @EmbeddedId
    @JsonIgnore
    var orderProductEntityId: OrderProductEntityId,

    @JsonBackReference
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @MapsId("orderId") // maps orderId attribute of embedded id
    var order: OrderEntity,

    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @MapsId("productId") // maps productId attribute of embedded id
    var product: ProductEntity,

    @Column(nullable = false)
    var quantity: Int = 0
)

注意新的 @MapsId 注释。

派生身份在第 2.4.1 节的 JPA 2.2 spec 中讨论(带示例)。