休眠:NoClassDefFoundError:使用休眠注释在初始化SessionFactory上的cfg /映射

时间:2019-01-09 17:27:48

标签: java sql-server hibernate intellij-idea

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

My project have this structure:

我想使用以下注释将简单的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的主体内部创建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

1 个答案:

答案 0 :(得分: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);
    }
}