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

 一、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 configuration = 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("[email protected]");
    	  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包和该例子的源代码,请评论去留言,我会给大家分享的!同时,如果代码有错误的地方或者有更好的想法,也可以在评论去留言

欢迎大家交流,共同学习进步!



猜你喜欢

转载自blog.csdn.net/alan_gaohaodong/article/details/79170056