您的位置:首页 > 移动开发

Hibernate报错 org.hibernate.MappingException: Unknown entity:

2018-01-26 15:41 411 查看
 一、Hibernate报错org.hibernate.MappingException: Unknown entity: XXX的原因

      有新手刚学到Hibernate时会看着视频或书来学习,但是视频里和书本上的代码都是几年前的Hibernate版本大部分低于Hibernate5.X,所以会出现一些错误。比如:

  信息: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.

           org.hibernate.MappingException: Unknown entity: com.hibtest1.entity.Users

当你仔细检查过后没有发现错误(照着书敲了一遍代码),其实是版本问题导致的错误。

       (1)//Hibernate4.X版本的写法

        //生成一个注册机对象

      ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();

       //使用注册机机对象serviceRegistry创建sessionFactory
sessionFactory = configuration.buildSessionFactory(serviceRegistry);

(2) //Hibernate5.X版本的写法
//生成一个注册机对象
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build();
//使用注册机机对象serviceRegistry创建sessionFactory
sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();

       (3)两者的工作原理差别解析:

           Hibernate4版本的SessionFactory实例构建的步骤是这样的(也是很多学习资料的通用范本):
//Configuration就是代表着hibernate的那个xml配置文件对象,如果configure方法中没有参数的话,默认是就是hibernate.cfg.xml。
Configuration conf = new Configuration().configure(); 
//选择Hibernate.cfg.xml 
Configuration conf = new Configuration().configure(“/Hibernate.cfg.xml”);
//服务注册,这是使用创建者模式,根据配置文件中的配置字段来构建注册服务(这应该是hibernate架构中注册服务的通用流程)。
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder(). 
applySettings(conf.getProperties()).build();
//使用实例化好了的注册服务,使用Configuration中的工厂模式实例化了SessionFactory 
SessionFactory sf = conf.buildSessionFactory(serviceRegistry);

如果你用的是Hibernate4的版本,这样做完全OK的,运行的时候不会报MappingException。
但是如果你使用Hibernate5的版本,就会报错。那么Hibernate5应该怎样构建SessionFactory呢,如下: 
//和V4版本比,V5版本看不到configure对象了。直接使用创建者模式构建出了标准服务注册对象 
//1. 配置类型安全的准服务注册类,这是当前应用的单例对象,不作修改,所以声明为final 
//在configure(“cfg/hibernate.cfg.xml”)方法中,如果不指定资源路径,默认在类路径下寻找名为hibernate.cfg.xml的文件 
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure(“cfg/hibernate.cfg.xml”).build();

//2. 根据服务注册类创建一个元数据资源集,同时构建元数据并生成应用一般唯一的的session工厂 
SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();

二、初学Hibernate的源代码例子(能运行):

            环境:(64bit)win10+MyEclipse2016+JDK1.8

            依赖jar包:从官网上下载的Hibernate(版本为:5.2.12.Final)包和MySQL连接驱动包(版本为:5.1.7)

           例子结构截图:

                             


             (1)HibernateSessionFactory.java

package com.hibtest1;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class HibernateSessionFactory {
//指定Hibernate配置文件路径
private static String CONFIG_FILE_LOCATION="/hibernate.cfg.xml";
//创建ThreadLocal对象
private static final ThreadLocal<Session> sessionThreadLocal=new ThreadLocal<Session>();
//创建Configuration对象
private static Configuration configuratio
c474
n = new Configuration();
//定义SessionFactory对象
private static SessionFactory sessionFactory;
//定义configFile属性并赋值
private static String configFile = CONFIG_FILE_LOCATION;
static{
try{
//读取配置文件hibernate.cfg.xml
configuration.configure();

/*
* Hibernate4.X版本的写法,不能运行有如下错误:
* 信息: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
* org.hibernate.MappingException: Unknown entity: com.hibtest1.entity.Users
*
* //生成一个注册机对象
* ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
*
* sessionFactory = configuration.buildSessionFactory(serviceRegistry);
*/

//Hibernate5.X版本的写法
//使用注册机机对象serviceRegistry创建sessionFactory//生成一个注册机对象
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build();
//使用注册机机对象serviceRegistry创建sessionFactory
sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
}catch(HibernateException e){
e.printStackTrace();
}
}

//创建无参的HibernateSessionFactory构造方法
private HibernateSessionFactory(){}
//获得SessionFactory对象
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
//重建SessionFActory
public static void rebuildSessionFactory(){
synchronized (sessionFactory) {
try{
configuration.configure(configFile);
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
//使用注册机机对象serviceRegistry创建sessionFactory
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
}catch(HibernateException e){
e.printStackTrace();
}
}
}

//获取Session对象
public static Session getSession(){
//获得ThreadLocal对象管理的Session对象
Session session = (Session)sessionThreadLocal.get();
try{
//判断Session对象是否已经存在或知否打开
if(session == null || !session.isOpen()){
//如果Session对象为空后未打开,再判断sessionFactory对象是否为空
if(sessionFactory == null){
//如果SessionFactory为空,则创建SessionFactory
rebuildSessionFactory();
}
//如果SessionFactory不为空,则打开Session
session = (sessionFactory != null)?sessionFactory.openSession():null;
sessionThreadLocal.set(session);
}
}catch(HibernateException e){
e.printStackTrace();
}
return session;
}

//关闭Session对象
public static void closeSession(){
Session session = (Session)sessionThreadLocal.get();
sessionThreadLocal.set(null);
try{
if(session != null && session.isOpen()){
session.close();
}
}catch(HibernateException e){
e.printStackTrace();
}
}

//configFile属性的set方法
public static void setConfigFile(String configFile){
HibernateSessionFactory.configFile = configFile;
sessionFactory = null;
}
//configuration属性的get方法
public static Configuration getConfiguration(){
return configuration;
}

}


(2)Users.java
package com.hibtest1.entity;

import java.io.Serializable;

public class Users implements Serializable {
private Integer id;
private String loginName;
private String loginPwd;
private String name;
private String address;
private String phone;
private String mail;

public Users(){ //空构造函数

}

public Integer getId() {
return id;
}

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

public String getLoginName() {
return loginName;
}

public void setLoginName(String loginName) {
this.loginName = loginName;
}

public String getLoginPwd() {
return loginPwd;
}

public void setLoginPwd(String loginPwd) {
this.loginPwd = loginPwd;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public String getPhone() {
return phone;
}

public void setPhone(String phone) {
this.phone = phone;
}

public String getMail() {
return mail;
}

public void setMail(String mail) {
this.mail = mail;
}

}
(3)Users.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.hibtest1.entity.Users" table="users" catalog="bookshop">
<id name="id" type="java.lang.Integer">
<column name="Id" />
<generator class="native"></generator>
</id>
<property name="loginName" type="java.lang.String">
<column name="LoginName" length="50" />
</property>
<property name="loginPwd" type="java.lang.String">
<column name="LoginPwd" length="16" />
</property>
<property name="name" type="java.lang.String">
<column name="Name" length="16" />
</property>
<property name="address" type="java.lang.String">
<column name="Address" length="16" />
</property>
<property name="phone" type="java.lang.String">
<column name="Phone" length="16" />
</property>
<property name="mail" type="java.lang.String">
<column name="Mail" length="16" />
</property>
</class>
</hibernate-mapping>
(4)TestAddUser.java
package com.hibtest1;

import org.hibernate.*;
import com.hibtest1.entity.Users;

public class TestAddUser {
public static void main(String[] args) {
new TestAddUser().addUser();
}

private void addUser(){
//创建实体类(瞬态对象)
Users user = new Users();
user.setLoginName("zhangsan");
user.setLoginPwd("123456");
user.setName("张三");
user.setAddress("江苏南京");
user.setPhone("0123456789");
user.setMail("123@qq.com");
Session session = HibernateSessionFactory.getSession();
Transaction tx = null;
try{
//开始一个事物
tx = session.beginTransaction();
//调用save方法持久化user对象,之后user对象转变为持久状态
session.save(user);
//提交事物,向数据库中插入一个新事物
tx.commit();
}catch(Exception e){
if(tx != null){
tx.rollback(); //事物回滚
}
e.printStackTrace();
}finally {
HibernateSessionFactory.closeSession(); //关闭session
//此时,user对象处于托管态
}

}
}
(5)hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="show_sql">true</property>
<property name="myeclipse.connection.profile">bookshop</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/bookshop
</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<mapping resource="com/hibtest1/entity/Users.hbm.xml" />
</session-factory>
</hibernate-configuration>

(6)运行结果截图:



(7)Navicat视图下数据库里的数据截图:



三、总结

    以上就是一个简单的例子,对于学习Hibernate入门的新手来说很适合,而且使用了配置文件,没有使用注解的方式。

ps:如果有新手想要相应的jar包和该例子的源代码,请评论去留言,我会给大家分享的!同时,如果代码有错误的地方或者有更好的想法,也可以在评论去留言

欢迎大家交流,共同学习进步!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: