You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

建模含复合键的一对多关系时出现ClassCastException的原因与解决方法

外键属于复合键的一对多关联报错解决

遇到的错误

class org.hibernate.mapping.BasicValue cannot be cast to class org.hibernate.mapping.ToOne

实体类代码

PointInTime 实体

@Entity
@Table(name = "point_in_time")
class PointInTime(
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long,
    val title: String,
    val note: String,
    @OneToMany(mappedBy = "symptom")
    val symptoms: Set<Symptom>
) {
    @field:Column(updatable = false)
    val createdAt: Instant = Instant.now()
}

Symptom 实体

@Entity
@Table(name = "symptom")
@IdClass(SymptomId::class)
class Symptom(
    @ManyToOne(optional = false)
    @Id
    @JoinColumn(name = "point_in_time_id", nullable = false)
    val pointInTime: PointInTime,
    @Id
    val category: String,
    @Id
    val symptom: String,
    val strength: Strength
)

SymptomId 主键类

class SymptomId (
    val pointInTime: Long,
    val category: String,
    val symptom: String
): Serializable

异常原因

核心错误是PointInTime类中@OneToMany的mappedBy属性值写错了:你指定的是"symptom",但Symptom实体里关联PointInTime的属性名是pointInTime。

Hibernate解析关联时,发现symptom是Symptom的基础类型主键字段,而非关联对象(ToOne类型),预期的关联映射类型和实际拿到的基础值类型不匹配,因此抛出类型转换异常。

解决方法

修改PointInTime中的@OneToMany注解,将mappedBy的值改为正确的属性名pointInTime:

@Entity
@Table(name = "point_in_time")
class PointInTime(
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long,
    val title: String,
    val note: String,
    // 修正mappedBy的属性名
    @OneToMany(mappedBy = "pointInTime")
    val symptoms: Set<Symptom>
) {
    @field:Column(updatable = false)
    val createdAt: Instant = Instant.now()
}

另外,SymptomId类的字段名和Symptom实体的主键字段完全匹配,这部分无需修改。

内容的提问来源于stack exchange,提问作者Shade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 15:20:19