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

Quarkus 3迁移时出现org.hibernate.mapping.BasicValue转ToOne类型转换错误

Quarkus v3.1.1.FINAL 迁移时Hibernate实体映射启动错误问题

我们正将Quarkus应用从v2版本迁移至v3.1.1.FINAL版本,在实体关系映射场景下遇到启动错误。

实体映射代码

Library实体

@Entity
@Data
public class Library {

    @Id
    Long id;
    
    String name;
    
    @OneToMany(mappedBy = "libraryId")
    List<Book> books;

}

Book实体

@Data
@Entity
public class Book {

    @Id
    Long id;

    Long libraryId;

    String name;

    @ManyToOne
    @JoinColumn(name = "library_id")
    Library library;

}

启动错误日志

2023-06-12 10:09:05,666 ERROR [io.qua.run.boo.StartupActionImpl] (Quarkus Main Thread) Error running Quarkus: java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at io.quarkus.runner.bootstrap.StartupActionImpl$1.run(StartupActionImpl.java:104)
        at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.ExceptionInInitializerError
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:70)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:44)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:124)
        at io.quarkus.runner.GeneratedMain.main(Unknown Source)
        ... 6 more
Caused by: java.lang.RuntimeException: Failed to start quarkus
        at io.quarkus.runner.ApplicationImpl.<clinit>(Unknown Source)
        ... 15 more
Caused by: java.lang.ClassCastException: class org.hibernate.mapping.BasicValue cannot be cast to class org.hibernate.mapping.ToOne (org.hibernate.mapping.BasicValue and org.hibernate.mapping.ToOne are in unnamed module of loader io.quarkus.bootstrap.classloading.QuarkusClassLoader @ef9296d)
        at org.hibernate.boot.model.internal.BinderHelper.checkMappedByType(BinderHelper.java:1086)
        at org.hibernate.boot.model.internal.CollectionBinder.isReversePropertyInJoin(CollectionBinder.java:1571)
        at org.hibernate.boot.model.internal.CollectionBinder.noAssociationTable(CollectionBinder.java:1582)
        at org.hibernate.boot.model.internal.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:1543)
        at org.hibernate.boot.model.internal.CollectionBinder$1.secondPass(CollectionBinder.java:1534)
        at org.hibernate.boot.model.internal.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:45)
        at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1857)
        at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1814)
        at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:328)
        at io.quarkus.hibernate.orm.runtime.boot.FastBootMetadataBuilder.build(FastBootMetadataBuilder.java:406)
        at io.quarkus.hibernate.orm.runtime.PersistenceUnitsHolder.createMetadata(PersistenceUnitsHolder.java:101)
        at io.quarkus.hibernate.orm.runtime.PersistenceUnitsHolder.constructMetadataAdvance(PersistenceUnitsHolder.java:73)
        at io.quarkus.hibernate.orm.runtime.PersistenceUnitsHolder.initializeJpa(PersistenceUnitsHolder.java:40)
        at io.quarkus.hibernate.orm.runtime.HibernateOrmRecorder$1.created(HibernateOrmRecorder.java:78)
        at io.quarkus.arc.runtime.ArcRecorder.initBeanContainer(ArcRecorder.java:79)
        at io.quarkus.deployment.steps.ArcProcessor$generateResources844392269.deploy_0(Unknown Source)
        at io.quarkus.deployment.steps.ArcProcessor$generateResources844392269.deploy(Unknown Source)
        ... 16 more

我们提供了包含完整依赖树的复现项目,项目内的tree.txt文件记录了所有依赖信息。


问题原因与解决方案

问题根源

@OneToMany注解的mappedBy属性配置错误:该属性应该指向关联实体(Book)中对应的实体对象属性,而非基本类型的外键字段。Quarkus v3.x升级了Hibernate ORM至6.x版本,对映射规则的校验更加严格,旧版本中可能容忍的错误配置在新版本中直接触发类型转换异常。

修复步骤

  1. 修正Library实体的@OneToMany映射:将mappedBy的值从libraryId改为library,对应Book实体中的关联实体属性。
  2. (推荐)移除冗余的外键字段:删除Book实体中的Long libraryId字段,Hibernate会通过@ManyToOne的library属性自动映射library_id数据库字段,手动维护基本类型外键易引发数据不一致问题。

修复后的实体代码

Library实体

@Entity
@Data
public class Library {

    @Id
    Long id;
    
    String name;
    
    @OneToMany(mappedBy = "library")
    List<Book> books;

}

Book实体

@Data
@Entity
public class Book {

    @Id
    Long id;

    String name;

    @ManyToOne
    @JoinColumn(name = "library_id")
    Library library;

}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 11:37:29