今日在使用OpenJPA学习 JPA2.0 的 CriteriaQuery 查询时,运行抛出如下错误:
16 openJPA WARN [main] openjpa.Runtime - The configuration property named "openjpa.ClassLoadEnhancement" was not recognized and will be ignored, although the name closely matches a valid property called "openjpa.PostLoadOnMerge". 70 openJPA INFO [main] openjpa.Runtime - Starting OpenJPA 2.4.2 257 openJPA INFO [main] openjpa.jdbc.JDBC - Using dictionary class "org.apache.openjpa.jdbc.sql.MySQLDictionary". 803 openJPA INFO [main] openjpa.jdbc.JDBC - Connected to MySQL version 5.5 using JDBC driver MySQL Connector Java version mysql-connector-java-5.1.46 ( Revision: 9cc87a48e75c2d2e87c1a293b2862ce651cb256e ). <openjpa-2.4.2-r422266:1777108 fatal user error> org.apache.openjpa.util.MetaDataException: The type "class com.huangx.openjpa.model.User" has not been enhanced. at org.apache.openjpa.meta.ClassMetaData.resolveMeta(ClassMetaData.java:1834) at org.apache.openjpa.meta.ClassMetaData.resolve(ClassMetaData.java:1808) at org.apache.openjpa.meta.MetaDataRepository.processBuffer(MetaDataRepository.java:829) at org.apache.openjpa.meta.MetaDataRepository.resolveMeta(MetaDataRepository.java:726) at org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.java:650) at org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:418) at org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:389) at org.apache.openjpa.persistence.meta.MetamodelImpl.find(MetamodelImpl.java:246) at org.apache.openjpa.persistence.meta.MetamodelImpl.entityImpl(MetamodelImpl.java:131) at org.apache.openjpa.persistence.criteria.CriteriaQueryImpl.from(CriteriaQueryImpl.java:350) at com.huangx.openjpa.Demo002.query(Demo002.java:24) at com.huangx.openjpa.Demo002.<init>(Demo002.java:39) at com.huangx.openjpa.Demo002.main(Demo002.java:53)
导致失败的原因是我没有将User实体配置到 <persistence-unit> 中。配置如下:
<persistence xmlns="https://java.sun.com/xml/ns/persistence" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" version="1.0"> <persistence-unit name="openJPA" transaction-type="RESOURCE_LOCAL"> //... <!-- 声明实体类【注意:导致错误的原因就是因为没有下面配置】 --> <class>com.huangx.openjpa.model.User</class> //... </persistence-unit> </persistence>
(1)实体类 User.java,如下:
package com.huangx.openjpa.model; import javax.persistence.*; @Entity @Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column private String name; @Column private Integer age; // 忽略了 get / set 方法 @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } }
(2)查询代码,如下:
private void query(EntityManager entityManager) { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<User> criteriaQuery = criteriaBuilder.createQuery(User.class); Root<User> root = criteriaQuery.from(User.class); TypedQuery<User> resultList = entityManager.createQuery(criteriaQuery); for(User user : resultList.getResultList()) { System.out.println(user); } }
上面将查询所有的用户信息。
(3)配置信息如下,如下:
<persistence xmlns="https://java.sun.com/xml/ns/persistence" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" version="1.0"> <persistence-unit name="openJPA" transaction-type="RESOURCE_LOCAL"> <!-- JPA提供者 --> <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> <!-- 声明实体类【注意:导致错误的原因就是因为没有下面配置】 --> <class>com.huangx.openjpa.model.User</class> <!-- 配置JPA数据库属性 --> <properties> <property name="openjpa.ConnectionURL" value="jdbc:mysql://localhost:3306/openjpa_learn?useSSL=false& serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8"/> <property name="openjpa.ConnectionDriverName" value="com.mysql.jdbc.Driver"/> <property name="openjpa.ConnectionUserName" value="root"/> <property name="openjpa.ConnectionPassword" value="aaaaaa"/> <!-- 自动生成表 --> <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/> <!-- 不使用加载时强化和编译时强化,使用运行时Unenhanced(不能发挥OpenJPA的最大效能,所以也不推荐) --> <property name="openjpa.ClassLoadEnhancement" value="false"/> <property name="openjpa.DynamicEnhancementAgent" value="false"/> <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/> </properties> </persistence-unit> </persistence>
总结:总的说来还是自己粗心了,忽略了实体的 <class> 配置,导致调用失败。