MappedSuperclass搭配泛型实体报无绑定类型无明确目标实体如何解决
解决方案
Hibernate作为ORM框架需要在启动阶段确定所有实体属性对应的数据库映射规则,无明确边界的泛型类型T无法被解析为具体的实体类,因此会抛出如下报错:
Property TokenAuthenticationEntity.user has an unbound type and no explicit target entity. Resolve this Generic usage issue or set an explicit target attribute
两种可落地的实现方案如下:
方案1:抽取泛型抽象父类,子类绑定具体类型(最通用,适配无共同继承体系的两类用户)
先定义标注了@MappedSuperclass的抽象泛型父类,复用通用属性和逻辑:@MappedSuperclass abstract class BaseTokenAuthenticationEntity<T>( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id: Long? = null, @NotNull abstract val user: T ) : BaseEntity()分别为内部、外部用户创建实体子类,指定具体的用户类型:
// 内部用户Token实体 @Entity(name = "InternalTokenAuthentication") class InternalTokenAuthenticationEntity( @ManyToOne(fetch = FetchType.EAGER) override val user: InternalUser ) : BaseTokenAuthenticationEntity<InternalUser>() // 外部用户Token实体 @Entity(name = "ExternalTokenAuthentication") class ExternalTokenAuthenticationEntity( @ManyToOne(fetch = FetchType.EAGER) override val user: ExternalUser ) : BaseTokenAuthenticationEntity<ExternalUser>()该方案会生成两张独立的Token数据表,逻辑完全隔离,兼容内部、外部用户表结构不一致的场景。
方案2:绑定泛型上界+指定targetEntity(适配两类用户有共同继承父类的场景)
如果内部、外部用户继承自同一个父类BaseUser,可直接给泛型加上界,同时在关联注解中指定目标实体为父类:@Entity(name = "TokenAuthentication") class TokenAuthenticationEntity<T : BaseUser>( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id: Long? = null, @NotNull @ManyToOne(fetch = FetchType.EAGER, targetEntity = BaseUser::class) val user: T, ) : BaseEntity()该方案只会生成一张Token数据表,
BaseUser需要搭配JPA继承注解使用,比如@Inheritance(strategy = InheritanceType.JOINED),适合两类用户属性重合度高的场景。
内容的提问来源于stack exchange,提问作者nykon
相关产品推荐
相关产品推荐

