【发布时间】: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