Spring JPA无法确定JdbcType:复合主键关联映射报错
问题解决:JPA复合主键映射错误
错误原因
报错Could not determine recommended JdbcType for me.offeex.inmyelement.entity.User的核心原因是:复合主键类EventDayId中直接引用了User实体类型。JPA要求主键类的字段必须是可序列化的基本类型(如Long、String)或简单值类型,不能直接使用实体对象作为主键字段。
修复步骤
1. 修正复合主键类EventDayId
将原有的User类型字段替换为对应用户主键的Long类型字段,确保类实现Serializable:
data class EventDayId( val userId: Long, val daysPassed: Long ) : Serializable
2. 调整EventDay实体的主键映射
保留user字段的@ManyToOne关联,添加@MapsId("userId")注解,将该关联映射到EventDayId中的userId字段,明确主键关联关系:
@Entity @Table(name = "days") @IdClass(EventDayId::class) class EventDay { @Id @MapsId("userId") // 关联到EventDayId的userId字段 @ManyToOne @JoinColumn(name = "user_id") lateinit var user: User @Id val daysPassed: Long = LocalDate.now().toEpochDay() @OneToMany(cascade = [CascadeType.ALL], orphanRemoval = true, mappedBy = "eventDay") lateinit var events: Set<Event> lateinit var description: String }
3. 在Event实体中添加EventDay关联
通过@JoinColumns指定复合主键的两个字段,完成Event到EventDay的关联映射:
@Entity @Table(name = "events") class Event { @Id @GeneratedValue var id: Long = 0 @ManyToOne @JoinColumn(name = "group_id") lateinit var group: EventGroup @ManyToOne @JoinColumns( JoinColumn(name = "user_id", referencedColumnName = "user_id"), JoinColumn(name = "daysPassed", referencedColumnName = "daysPassed") ) lateinit var eventDay: EventDay var rating: Byte = 0 lateinit var icon: URL }
关键说明
@MapsId注解用于将实体关联字段映射到复合主键类中的对应字段,解决JPA无法识别实体类型主键的问题。- 复合主键类的字段名称需要与实体中对应的主键映射字段名称保持一致(如
userId对应EventDay中user关联的主键字段)。 Event中的@JoinColumns必须完全匹配EventDay复合主键的两个列名,确保关联关系正确建立。
内容的提问来源于stack exchange,提问作者OffeeX
相关产品推荐
相关产品推荐

