尝试使用 Hibernate 持久化实体时出错(MappingException:未知实体)
Posted
技术标签:
【中文标题】尝试使用 Hibernate 持久化实体时出错(MappingException:未知实体)【英文标题】:Error when try to persist entity with Hibernate (MappingException: Unknown entity) 【发布时间】:2016-04-01 04:10:02 【问题描述】:我在一个独立的 maven java 应用程序中使用 Hibernate 5.0.6 和 Hibernate annotations 3.5.6-Final 和 mysql 5.1.37。
我正在尝试制作一个简单的持久性示例,但是当我调用 save 时收到以下错误:
0 [main] ERROR edu.uci.ics.crawler4j.crawler.CrawlController - Error happened
org.hibernate.MappingException: Unknown entity: br.com.alexpfx.supermarket.crawler.model.domain.Product
类是通过配置文件中的映射类来指向的。但是找不到。
<mapping class="br.com.alexpfx.supermarket.crawler.model.domain.Product" />
但是当我在HibernateUtil
中这样做时:
configure.addAnnotatedClass(Product.class);
configure.addAnnotatedClass(Manufacturer.class);
它有效。但我想点映射xml文件中的类。
我发现了几个与此相关的错误,但没有找到解决我的问题的解决方案。我觉得我做错了什么。
错误的完整堆栈跟踪:
0 [main] ERROR edu.uci.ics.crawler4j.crawler.CrawlController - Error happened
org.hibernate.MappingException: Unknown entity: br.com.alexpfx.supermarket.crawler.model.domain.Product
at org.hibernate.internal.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:781)
at org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.java:1520)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:100)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:679)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:671)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:666)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:338)
at com.sun.proxy.$Proxy19.save(Unknown Source)
at br.com.alexpfx.supermarket.crawler.crawler.mercadoribeirao.MercadoRibeiraoCrawler.init(MercadoRibeiraoCrawler.java:47)
at br.com.alexpfx.supermarket.crawler.crawler.Crawler.<init>(Crawler.java:16)
at br.com.alexpfx.supermarket.crawler.crawler.mercadoribeirao.MercadoRibeiraoCrawler.<init>(MercadoRibeiraoCrawler.java:26)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at java.lang.Class.newInstance(Class.java:442)
at edu.uci.ics.crawler4j.crawler.CrawlController.start(CrawlController.java:158)
at edu.uci.ics.crawler4j.crawler.CrawlController.start(CrawlController.java:133)
at br.com.alexpfx.supermarket.crawler.crawler.CrawlerStarter.start(CrawlerStarter.java:41)
at br.com.alexpfx.supermarket.crawler.Main.save(Main.java:29)
at br.com.alexpfx.supermarket.crawler.Main.main(Main.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
配置文件位于:project\src\main\resources\hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.url">jdbc:mysql://localhost:3306/smket</property>
<property name="connection.username">alex</property>
<property name="connection.password">123alex</property>
<property name="connection.pool_size">5</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<property name="hibernate.current_session_context_class">thread</property>
<mapping class="br.com.alexpfx.supermarket.crawler.model.domain.Product" />
<mapping class="br.com.alexpfx.supermarket.crawler.model.domain.Manufacturer" />
</session-factory>
</hibernate-configuration>
HibernateUtil
:
public class HibernateUtil
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory()
try
Configuration configure = new Configuration().configure("hibernate.cfg.xml");
/*
configure.addAnnotatedClass(Product.class);
configure.addAnnotatedClass(Manufacturer.class);
*/
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configure.getProperties()).build();
return configure.buildSessionFactory(serviceRegistry);
catch (Throwable ex)
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
public static SessionFactory getSessionFactory()
return sessionFactory;
public static void shutdown()
getSessionFactory().close();
POJO 类:
package br.com.alexpfx.supermarket.crawler.model.domain;
import javax.persistence.*;
@Entity
@Table(name = "tb_produtos")
public class Product implements BaseEntity
public Product()
Product(Integer id, Manufacturer manufacturer, String description, String url, Keywords keywords)
this.id = id;
this.manufacturer = manufacturer;
this.description = description;
this.url = url;
this.keywords = keywords;
@Id
@GeneratedValue
private Integer id;
@ManyToOne
@JoinColumn(name = "ID_FABRICANTE")
private Manufacturer manufacturer;
@Column(name = "DESCRICAO")
private String description;
@Column(name = "URL")
private String url;
@Transient
private Keywords keywords;
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
public Manufacturer getManufacturer()
return manufacturer;
public void setManufacturer(Manufacturer manufacturer)
this.manufacturer = manufacturer;
public String getDescription()
return description;
public void setDescription(String description)
this.description = description;
public String getUrl()
return url;
public void setUrl(String url)
this.url = url;
public Keywords getKeywords()
return keywords;
public void setKeywords(Keywords keywords)
this.keywords = keywords;
【问题讨论】:
【参考方案1】:这已经是 Hibernate 5 配置构建的一个熟悉问题。不能使用 Hibernate 4 的配置方式来配置 Hibernate 5。所以就用这个
private static SessionFactory buildSessionFactory()
try
return new Configuration().configure().buildSessionFactory();
catch (Throwable ex)
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
您可以参考this 了解更多说明。我已经实现了一个配置构建器,它可以很好地与 Hibernate 4 和 Hibernate 5 配合使用,你也可以看看它ConfigurationBuilder。
【讨论】:
【参考方案2】:您没有指定休眠配置文件hibernate.cfg.xml
的位置。
hibernate.cfg.xml
文件用于设置与数据库交互所需的所有配置。因此,在那里定义了数据库以及数据库用户凭据。方言设置为 MySQL,驱动程序为com.mysql.jdbc.Driver
。还有一个映射属性,其中定义了实体类。
您还可以在此处设置特定的数据库选项,例如每次创建 sessionFactory
时是创建还是更新架构。这是在hibernate.hbm2ddl.auto
属性中配置的,该属性设置为update
。所以模式只更新。如果此属性设置为 create,那么每次我们运行您的应用程序时,都会重新创建模式,从而删除以前的数据。这里设置的另一个属性是show_sql
,它指定sql查询是显示在控制台还是记录器中。
首先,getSessionFactory()
是一个提供SessionFactory
的方法,Session
s 的创建者,Java 应用程序和 Hibernate 之间的基本接口。 SessionFactory
是用StandardServiceRegistryBuilder
构建的,利用Configuration
。 Configuration
是您可以在创建SessionFactory
时指定要使用的属性和映射文档的地方。
因此,每个与数据库交互的方法都会得到一个Session
,利用getSessionFactory()
,以及使用SessionFactory
的openSession()
API 方法。
public static SessionFactory getSessionFactory()
Configuration configuration = new Configuration().configure();
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties());
SessionFactory sessionFactory = configuration
.buildSessionFactory(builder.build());
return sessionFactory;
【讨论】:
程序正在读取配置文件,因为当我这样做时:configure.addAnnotatedClass 它可以工作。即使这样,如果他无法读取配置文件,它会在从new Configuration()调用.configure()时停止,但正确调用getSessionFactory方法。 我真的很抱歉,但是您的方法仅适用于 Hibernate 4 及更低版本。对于 Hibernate 5,这是不正确的。请参阅我的回答以获取更多说明。以上是关于尝试使用 Hibernate 持久化实体时出错(MappingException:未知实体)的主要内容,如果未能解决你的问题,请参考以下文章
org.hibernate.PersistentObjectException:传递给持久化的分离实体:多对一单向