OpenJPA抛出 The type * has not been enhanced 错误

本文将介绍怎样处理JPA抛出的“org.apache.openjpa.util.MetaDataException: The type "class com.huangx.openjpa.model.User" has not been enhanced.”错误。

今日在使用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&amp;
                      serverTimezone=UTC&amp;useUnicode=true&amp;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> 配置,导致调用失败。

最困难的事情就是认识自己。——希腊
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号