我正在尝试使用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
的主体内部创建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
答案 0 :(得分:1)
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);
}
}