升级至Java 11后JPA命名查询编译失败,请求排查修复
问题:Java 11下EclipseLink无法识别JPQL中的实体类
问题背景
原本在Java 8环境正常运行的JPQL命名查询,升级到Java 11搭配EclipseLink后编译失败。
命名查询语句
<named-query name="XXDataHist.findLatestByObjectClassTypeAndObjectIdAndEventTime"> <query>select obj from XXDataHist obj WHERE obj.objectId = :objectId AND obj.objectClassType = :classType AND obj.createTime <= :createTime ORDER BY obj.id DESC</query> </named-query>
报错信息
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: Exception [EclipseLink-28019] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.EntityManagerSetupException| Exception Description: Deployment of PersistenceUnit [defaultPU] failed. Close all factories for this PersistenceUnit.| Internal Exception: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.JPQLException| Exception Description: Problem compiling [select obj from XXDataHist obj where obj.objectId = :objectId and | obj.objectClassType = :classType and | obj.createTime <= :createTime ORDER BY obj.id DESC]. |[16, 26] The abstract schema type 'XXDataHist' is unknown. |[37, 49] The state field path 'obj.objectId' cannot be resolved to a valid type. |[66, 85] The state field path 'obj.objectClassType' cannot be resolved to a valid type. |[103, 117] The state field path 'obj.createTime' cannot be resolved to a valid type. |[142, 148] The state field path 'obj.id' cannot be resolved to a valid type.
实体类代码
@Entity @Cacheable @XmlRootElement @Table(name = "x_data_hist") public class XXDataHist implements java.io.Serializable { private static final long serialVersionUID = 1L; @Id @SequenceGenerator(name = "x_data_hist_SEQ", sequenceName = "x_data_hist_SEQ", allocationSize = 1) @GeneratedValue(strategy = GenerationType.AUTO, generator = "x_data_hist_SEQ") @Column(name = "id") protected Long id; @Temporal(TemporalType.TIMESTAMP) @Column(name = "CREATE_TIME") protected Date createTime = DateUtil.getUTCDate(); @Temporal(TemporalType.TIMESTAMP) @Column(name = "UPDATE_TIME") protected Date updateTime = DateUtil.getUTCDate(); @Column(name = "version") protected Long version; @Column(name = "obj_guid") protected String objectGuid; @Column(name = "obj_class_type") protected Integer objectClassType; @Column(name = "obj_id") protected Long objectId; @Column(name = "obj_name") protected String objectName; @Column(name = "action") protected String action; @Temporal(TemporalType.TIMESTAMP) @Column(name = "from_time") protected Date fromTime; @Temporal(TemporalType.TIMESTAMP) @Column(name = "to_time") protected Date toTime; @Column(name = "content") protected String content; // constructor, equals, toString, getters and setters }
原因分析
- EclipseLink版本不兼容:你当前用的EclipseLink 2.5.2是2014年的老版本,完全不支持Java 11。Java 9+引入了模块化系统(JPMS),旧版本的EclipseLink无法适配新的类加载机制,导致无法扫描和识别实体类。
- 实体扫描配置缺失:Java 11下,JPA的实体自动扫描逻辑可能因为类路径变化或模块化限制失效,导致EclipseLink找不到
XXDataHist实体,JPQL自然无法识别对应的抽象schema类型。
修复方案
1. 升级EclipseLink版本
至少升级到支持Java 11的版本,推荐用EclipseLink 2.7.10+(2.7.x系列支持Java 8-17,3.x系列支持Java 11+)。
Maven依赖更新示例:
<dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>2.7.10</version> </dependency>
2. 确保实体类被正确扫描
- 在
persistence.xml中显式声明实体类:<persistence-unit name="defaultPU"> <class>com.yourpackage.XXDataHist</class> <!-- 其他实体类按需添加 --> <!-- 其他配置保持不变 --> </persistence-unit> - 如果用Spring Boot,添加
@EntityScan注解指定实体所在包:@SpringBootApplication @EntityScan(basePackages = "com.yourpackage.entity") // 替换为你的实体实际包路径 public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } }
3. 优化JPQL语句(可选)
原语句逻辑没问题,可调整格式提升可读性(XML中的<=已正确转义为<=,无需修改):
<named-query name="XXDataHist.findLatestByObjectClassTypeAndObjectIdAndEventTime"> <query>SELECT obj FROM XXDataHist obj WHERE obj.objectId = :objectId AND obj.objectClassType = :classType AND obj.createTime <= :createTime ORDER BY obj.id DESC</query> </named-query>
内容的提问来源于stack exchange,提问作者NikhilP
相关产品推荐
相关产品推荐

