【问题标题】:JPA Composite Key that references another Composite Key引用另一个复合键的 JPA 复合键
【发布时间】:2026-02-02 14:30:01
【问题描述】:

我有三个表,其中两个有一个复合主键,其中一个复合键引用另一个:

VEHICLE
| MAKE | MODEL | NOTES |
Primary Key = Make + Model

VEHICLE_LABEL
| VEH_MAKE | VEH_MODEL | LAB_ID | ORDER |
Primary Key = VEH_MAKE + VEH_MODEL + LAB_ID

LABEL
| ID | NAME | NOTES |
Primary Key = ID

由于连接表上的额外列,我将VehicleLabel 创建为自己的Entity

车辆:

@Entity
@Table(name = "VEHICLE")
class Vehicle @PersistenceConstructor constructor(
    @EmbeddedId
    val key: ID,

    @Column(name = "NOTES")
    val notes: String
) {
    @Embeddable
    class ID(
        @Column(name = "MAKE")
        val make: String,

        @Column(name = "MODEL")
        val model: String
    ) : Serializable
}

车辆标签:

@Entity
@Table(name = "VEHICLE_LABEL")
class VehicleLabel @PersistenceConstructor constructor(
    @EmbeddedId
    val key: ID,

    @Column(name = "ORDER")
    val order: Int
) {
    @Embeddable
    class ID @PersistenceConstructor constructor(
        @ManyToOne
        @JoinColumns(
            JoinColumn(name = "VEH_MAKE", referencedColumnName = "MAKE"),
            JoinColumn(name = "VEH_MODEL", referencedColumnName = "MODEL")
        )
        val vehicle: Vehicle,

        @ManyToOne
        @JoinColumn(name = "LAB_ID")
        val label: Label
    ) : Serializable
}

标签:

@Entity
@Table(name = "LABEL")
class Label(
    @Id
    @Column(name = "ID")
    val id: String,

    @Column(name = "NAME")
    val name: String

    @Column(name = "NOTES")
    val notes: String
)

当我运行上述内容时,我得到了

InvalidDataAccessApiUsageException: Provided id of the wrong type for class repository.Vehicle. Expected: class repository.Vehicle$ID, got class java.lang.String

我尝试交换VehicleLabel.ID,以便包含Vehicle,而不是包含完整的Vehicle.ID,但我得到了同样的错误。理想情况下,我不想这样做。

注意:我试图避免将 ID 添加到 VEHICLE 表中,因为已经通过 MAKE + MODEL 确保了唯一性

我做错了什么?

【问题讨论】:

    标签: hibernate kotlin spring-data-jpa spring-data


    【解决方案1】:

    原来错误来自调用 entityManager.find(Vehicle::class, "model") 的测试类。

    这是车辆 ID 只是 model 字段时的遗留问题。

    【讨论】: