使用ObjectDB时JPA继承遇「字段未找到」错误的解决求助
问题分析
你遇到的核心问题是:使用ObjectDB作为JPA提供者时,JPQL查询无法识别继承链中父类Item的retired字段,报错提示该字段不存在于Vtm类中;但相同代码在EclipseLink+MySQL环境下可正常运行,切换@MappedSuperclass继承模式后问题依然存在。这是因为ObjectDB对JPA继承字段的映射解析有更严格的显式要求,与关系型数据库的JPA提供者实现细节存在差异。
解决方案
1. 补全父类字段的JPA注解,统一访问策略
ObjectDB对未显式标注的字段不会自动映射(其他JPA提供者可能支持隐式映射),需给Item类的retired字段添加完整的JPA注解,并确保访问策略统一(要么全用字段级注解,要么全用getter级注解,禁止混合)。
修改Item类代码:
@Entity public class Item implements Serializable, Comparable<Item> { @Column(name = "retired") // 显式指定数据库列映射 private boolean retired; // 改为private保证封装性,JPA可正常识别 // 必须提供对应的getter/setter方法 public boolean isRetired() { return retired; } public void setRetired(boolean retired) { this.retired = retired; } // other fields, getters, and setters }
2. 调整JPQL查询,显式引用父类字段(针对@Inheritance实体继承模式)
如果使用@Inheritance的实体继承方案,可在JPQL中通过显式指定父类路径的方式访问字段:
String jpql = "Select vtm " + " from Vtm vtm " + " where vtm.Item.retired=:ret " // 显式指向父类Item的字段 + " order by vtm.name";
或者通过JOIN关联父类的方式查询:
String jpql = "Select vtm " + " from Vtm vtm join Item i on vtm.id = i.id " + " where i.retired=:ret " + " order by vtm.name";
3. 升级ObjectDB到最新稳定版
部分旧版本的ObjectDB对JPA继承特性的支持存在bug,升级到最新稳定版(如2.8.x系列)可修复此类兼容性问题。
4. 校验实体继承链的注解正确性
确保继承链中的每个类注解符合JPA规范:
- 使用
@Inheritance时,所有层级类都需标注@Entity; - 使用
@MappedSuperclass时,只有最终子类标注@Entity,父类仅标注@MappedSuperclass; - 所有实体类正确实现
Serializable,可添加serialVersionUID避免序列化问题。
验证步骤
- 先修改
Item类,补全retired字段的注解和getter/setter; - 运行原JPQL查询,查看是否解决报错;
- 若仍有问题,尝试调整JPQL的字段引用方式;
- 最后考虑升级ObjectDB版本。
内容的提问来源于stack exchange,提问作者Buddhika Ariyaratne
相关产品推荐
相关产品推荐

