【问题标题】:Hibernate: NoClassDefFoundError: cfg/Mappings on init SessionFactory using Hibernate AnnotationsHibernate: NoClassDefFoundError: cfg/Mappings on init SessionFactory using Hibernate Annotations
【发布时间】:2019-06-04 12:59:17
【问题描述】:

我正在尝试使用 SQL Server 2014 数据库在 IntelliJ 中运行基本的 Tutorialspoint Hibernate Annotation Mapping example 项目。

我想使用这样的注释将来自简单 Employee 类的数据存储到数据库中:

package com.example;

import javax.persistence.*;

@Entity
@Table(name = "EMPLOYEE")
public class Employee {
    @Id @GeneratedValue
    @Column(name = "id")
    private int id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "salary")
    private int salary;

    public Employee() {}

    public int getId() {
        return id;
    }

    public void setId( int id ) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName( String first_name ) {
        this.firstName = first_name;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName( String last_name ) {
        this.lastName = last_name;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary( int salary ) {
        this.salary = salary;
    }
}

每当我想在 HibernateTest 的 main 中创建 SessionFactory 实例时,就会出现问题:

package com.example;

import java.util.List;
import java.util.Iterator;
import java.util.logging.Logger;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateTest {

    private static SessionFactory factory;
    private static final Logger logger = Logger.getLogger(HibernateTest.class.getName());

    public static void main(String[] args) {

        // SessionFactory option A)
        try {
            factory = new AnnotationConfiguration().
                    configure().
                    addPackage("com.example").
                            addAnnotatedClass(Employee.class).
                            buildSessionFactory();
        } catch (Throwable e) {
            System.err.println("Failed to create sessionFactory object." + e);
            throw new ExceptionInInitializerError(e);
        }

        // SessionFactory option B)
        /*
        try {
            StandardServiceRegistry ssr = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build();
            Metadata meta = new MetadataSources(ssr).getMetadataBuilder().build();
            factory = meta.getSessionFactoryBuilder().build();
        }catch (Throwable e) {
            System.err.println("Failed to create sessionFactory object." + e);
            throw new ExceptionInInitializerError(e);
        }
        */

        // SessionFactory option C)
        /*
        try{
            Configuration configuration = new Configuration();
            configuration.configure("hibernate.cfg.xml");
            StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
            factory = configuration.buildSessionFactory(ssrb.build());
        } catch (Throwable e) {
            System.err.println("Failed to create sessionFactory object." + e);
            throw new ExceptionInInitializerError(e);
        }
        */

        HibernateTest ME = new HibernateTest();

        /* Add few employee records in database */
        Integer empID1 = ME.addEmployee("Zara", "Ali", 1000);
        Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
        Integer empID3 = ME.addEmployee("John", "Paul", 10000);

        /* List down all the employees */
        ME.listEmployees();

        /* Update employee's records */
        ME.updateEmployee(empID1, 5000);

        /* Delete an employee from the database */
        ME.deleteEmployee(empID2);

        /* List down new list of the employees */
        ME.listEmployees();
    }


    /* Method to CREATE an employee in the database */
    public Integer addEmployee(String fname, String lname, int salary){
        Session session = factory.openSession();
        Transaction tx = null;
        Integer employeeID = null;

        try {
            tx = session.beginTransaction();
            Employee employee = new Employee();
            employee.setFirstName(fname);
            employee.setLastName(lname);
            employee.setSalary(salary);
            employeeID = (Integer) session.save(employee);
            tx.commit();
        } catch (HibernateException e) {
            if (tx!=null) tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
        return employeeID;
    }

    /* Method to  READ all the employees */
    public void listEmployees( ){
        Session session = factory.openSession();
        Transaction tx = null;

        try {
            tx = session.beginTransaction();
            List employees = session.createQuery("FROM Employee").list();
            for (Iterator iterator = employees.iterator(); iterator.hasNext();){
                Employee employee = (Employee) iterator.next();
                System.out.print("First Name: " + employee.getFirstName());
                System.out.print("  Last Name: " + employee.getLastName());
                System.out.println("  Salary: " + employee.getSalary());
            }
            tx.commit();
        } catch (HibernateException e) {
            if (tx!=null) tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

    /* Method to UPDATE salary for an employee */
    public void updateEmployee(Integer EmployeeID, int salary ){
        Session session = factory.openSession();
        Transaction tx = null;

        try {
            tx = session.beginTransaction();
            Employee employee = (Employee)session.get(Employee.class, EmployeeID);
            employee.setSalary( salary );
            session.update(employee);
            tx.commit();
        } catch (HibernateException e) {
            if (tx!=null) tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

    /* Method to DELETE an employee from the records */
    public void deleteEmployee(Integer EmployeeID){
        Session session = factory.openSession();
        Transaction tx = null;

        try {
            tx = session.beginTransaction();
            Employee employee = (Employee)session.get(Employee.class, EmployeeID);
            session.delete(employee);
            tx.commit();
        } catch (HibernateException e) {
            if (tx!=null) tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
}

我一直在寻找很多可能的解决方案,但没有结果。有很多 SessionFactory 构造选项 - 所以我基本上尝试了 3 个 SessionFactory 构造选项: 每当我使用选项 A 执行程序时,就像在教程中一样,我得到了一个

Caused by: java.lang.NoClassDefFoundError: org/hibernate/cfg/Mappings
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at com.example.HibernateTest.main(HibernateTest.java:28)
Caused by: java.lang.ClassNotFoundException: org.hibernate.cfg.Mappings
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 13 more

我发现通常的修复方法是稍微修改hibernate.cfg.xml,但是如果有错误,我看不到任何内容:

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>

        <property name = "hibernate.dialect">
            <!-- org.hibernate.dialect.MySQLDialect -->
            org.hibernate.dialect.SQLServerDialect
        </property>

        <property name = "hibernate.connection.driver_class">
            <!--com.mysql.jdbc.Driver-->
            com.microsoft.sqlserver.jdbc.SQLServerDriver
        </property>

        <!-- Assume test is the database name -->

        <property name = "hibernate.connection.url">
            <!--jdbc:mysql://localhost/hibernatest-->
            jdbc:sqlserver://OBVIOUS\SQLEXPRESS:1433;databaseName=hibernatest
        </property>

        <property name = "hibernate.connection.username">
            pepa
        </property>

        <property name = "hibernate.connection.password">
            pepa
        </property>

        <!-- List of XML mapping files -->
        <mapping class = "com.example.Employee"/>

    </session-factory>
</hibernate-configuration>

选项 B 和 C 结束如下:

Failed to create sessionFactory object.java.lang.NoSuchMethodError: org.hibernate.cfg.annotations.reflection.JPAMetadataProvider.<init>(Lorg/hibernate/boot/spi/MetadataBuildingOptions;)V
Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.example.HibernateTest.main(HibernateTest.java:45)
Caused by: java.lang.NoSuchMethodError: org.hibernate.cfg.annotations.reflection.JPAMetadataProvider.<init>(Lorg/hibernate/boot/spi/MetadataBuildingOptions;)V
    at org.hibernate.boot.internal.MetadataBuilderImpl$MetadataBuildingOptionsImpl.generateDefaultReflectionManager(MetadataBuilderImpl.java:742)
    at org.hibernate.boot.internal.MetadataBuilderImpl$MetadataBuildingOptionsImpl.<init>(MetadataBuilderImpl.java:715)
    at org.hibernate.boot.internal.MetadataBuilderImpl.<init>(MetadataBuilderImpl.java:127)
    at org.hibernate.boot.internal.MetadataBuilderImpl.<init>(MetadataBuilderImpl.java:94)
    at org.hibernate.boot.MetadataSources.getMetadataBuilder(MetadataSources.java:125)
    at com.example.HibernateTest.main(HibernateTest.java:41)

有关完整信息,我正在添加 Gradle 配置:

编辑:添加hibernate-core并删除hibernate-annotations

apply plugin: 'java'

group 'HibernateExample3'
version '0.0.0'

sourceCompatibility = 1.8

buildscript {
    repositories {
        mavenCentral()
        maven { url "http://repo.maven.apache.org/maven2" }
        maven { url "https://repo.spring.io/release" }
        mavenLocal()
    }
    dependencies {
        classpath "org.springframework.boot:spring-boot-gradle-plugin:1.5.4.RELEASE"
    }
}

repositories {
    mavenCentral()
}

    dependencies {
    compile group: 'org.hibernate', name: 'hibernate-core', version: '5.4.0.Final'
    compile group: 'org.hibernate', name: 'hibernate-gradle-plugin', version: '5.4.0.Final'
    //compile group: 'org.hibernate', name: 'hibernate-annotations', version: '3.5.6-Final'
    //compile group: 'mysql', name: 'mysql-connector-java', version: '6.0.6'
    compile 'org.springframework.boot:spring-boot-starter-web:1.5.4.RELEASE'
    compile 'org.springframework:spring-context:4.3.4.RELEASE'
    compile "javax.inject:javax.inject:1"

    testCompile group: 'com.microsoft.sqlserver', name: 'mssql-jdbc', version: '7.0.0.jre8'
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

修复后,我无法再使用选项 A。但是,SQL Server 驱动程序发生了一个新错误:

Failed to create sessionFactory object.org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.example.HibernateTest.main(HibernateTest.java:58)
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:275)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:175)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:119)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:84)
    at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:474)
    at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:85)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:689)
    at com.example.HibernateTest.main(HibernateTest.java:55)
Caused by: org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [com.microsoft.sqlserver.jdbc.SQLServerDriver]
    at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:136)
    at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.loadDriverIfPossible(DriverManagerConnectionProviderImpl.java:149)
    at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.buildCreator(DriverManagerConnectionProviderImpl.java:105)
    at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.buildPool(DriverManagerConnectionProviderImpl.java:89)
    at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.configure(DriverManagerConnectionProviderImpl.java:73)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:100)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:246)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:94)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
    ... 13 more
Caused by: java.lang.ClassNotFoundException: Could not load requested class : com.microsoft.sqlserver.jdbc.SQLServerDriver
    at org.hibernate.boot.registry.classloading.internal.AggregatedClassLoader.findClass(AggregatedClassLoader.java:210)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:133)
    ... 25 more

【问题讨论】:

  • 为什么没有hibernate-core 依赖?
  • 本教程基于较旧的休眠版本(休眠 3.6.4)...当前休眠版本>5 ...您使用“5.2.0.-Final”...” hibernate-annotations”似乎也过时了(但我知道它是可用的最新版本......当你排除它时有任何问题吗?......并使用最新的 hibernate-gradle-plugin..)
  • @LaksithaRanasingha,好点,添加了hibernate-core,但没有效果。
  • @xerx593,它帮助了我一点。删除hibernate-annotations 后,我不能再使用选项A。执行后有一些效果:之前JPAMetadataProvider导致的NoSuchMethodError,现在是SQL驱动导致的。
  • 你在运行“测试”吗? (因为您将 sql 驱动程序声明为测试部门。)..并且依赖项(物理上)是否可用..并且在底层类路径(运行/测试)上?

标签: java sql-server hibernate intellij-idea


【解决方案1】:

Hibernate Tutorialspoint 使用 Hibernate 3 是过时的。关于 Hibernate 5 的好教程有 o7planning.org.

不需要 Gradle 插件或 hibernate-annotationshibernate-core 和数据库驱动程序就足够了。进入build.gradle添加这个:

compile group: 'org.hibernate', name: 'hibernate-core', version: '5.2.2.Final'
compile group: 'net.sourceforge.jtds', name: 'jtds', version: '1.3.1'

并制作 SessionFactory:

// Hibernate 5:
private static SessionFactory buildSessionFactory() {
    try {
        // Create the ServiceRegistry from hibernate.cfg.xml
        ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()//
                .configure("hibernate.cfg.xml").build();

        // Create a metadata sources using the specified service registry.
        Metadata metadata = new MetadataSources(serviceRegistry).getMetadataBuilder().build();

        return metadata.getSessionFactoryBuilder().build();
    } catch (Throwable ex) {

        System.err.println("Initial SessionFactory creation failed." + ex);
        throw new ExceptionInInitializerError(ex);
    }
}

【讨论】:

    猜你喜欢
    • 2012-10-20
    • 1970-01-01
    • 2014-11-03
    • 2014-08-26
    • 2021-06-10
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2016-07-14
    相关资源
    最近更新 更多