Hibernate: NoClassDefFoundError: cfg / Отображения в init SessionFactory с использованием аннотаций Hibernate - PullRequest
0 голосов
/ 09 января 2019

Я пытаюсь запустить базовый Пример сопоставления аннотаций в Hibernate * Проект 1002 * в IntelliJ с базой данных SQL Server 2014.

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;
    }
}

Проблема появляется, когда я хочу создать экземпляр SessionFactory внутри main HibernateTest:

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'
}

После этого исправления я больше не могу использовать опцию А. Однако с драйвером 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 голосов
/ 10 января 2019

Hibernate Tutorialspoint использование Hibernate 3 является архаичным. Хороший учебник о Hibernate 5 имеет o7planning.org .

Никаких плагинов Gradle или hibernate-annotations не требуется. hibernate-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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...