【问题标题】:org.hibernate.MappingException: Unknown entityorg.hibernate.MappingException:未知实体
【发布时间】:2011-04-29 10:39:22
【问题描述】:

我正在尝试完成Beginning Hibernate 第2 版,但我一直在尝试将简单的工作示例与HSQLDB 放在一起。

当我运行 ant populateMessages 时,我得到了

[java] org.hibernate.MappingException: Unknown entity: sample.entity.Message
[java]     at org.apache.tools.ant.taskdefs.ExecuteJava.execute(ExecuteJava.java:194)
[java]     at org.apache.tools.ant.taskdefs.Java.run(Java.java:747)
...

这是我得到的:

Message.java

package sample.entity;

import org.hibernate.annotations.Entity;

import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
public class Message
{
    private String messageText;
    private Integer id;

    public Message( String messageText )
    {
        this.messageText = messageText;
    }

    public Message()
    {
    }

    public String getMessageText()
    {
        return messageText;
    }

    public void setMessageText(String messageText)
    {
        this.messageText = messageText;
    }

    @Id
    @GeneratedValue
    public Integer getId()
    {
        return id;
    }

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

PopulateMessages.java

package sample;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import sample.entity.Message;

import java.util.Date;

public class PopulateMessages
{
    public static void main(String[] args)
    {
        SessionFactory factory = new AnnotationConfiguration().configure().buildSessionFactory();
        Session session = factory.openSession();
        session.beginTransaction();

        Message m1 = new Message("Hibernated a  messages on " + new Date());
        session.save(m1);
        session.getTransaction().commit();
        session.close();
    }
}

build.properties

# Path to the hibernate install directory
hibernate.home=C:/hibernate/hibernate-3.5.6
# Path to the hibernate-tools install directory
hibernate.tools.home=C:/hibernate/hibernate-tools
# Path to hibernate-tools.jar relative to hibernate.tools.home
hibernate.tools.path=/plugins/org.hibernate.eclipse_3.3.1.v201006011046R-H111-GA/lib/tools
# Path to hibernate-tools hibernate libraries relative to hibernate.tools.home
hibernate.tools.lib.path=/plugins/org.hibernate.eclipse_3.3.1.v201006011046R-H111-GA/lib/hibernate
# Path to the SLF4J implementation JAR for the logging framework to use
slf4j.implementation.jar=lib/slf4j-simple-1.6.1.jar
# Path to the HSQL DB install directory
hsql.home=C:/hsqldb

hibernate.cfg.xml

<!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="hibernate.connection.url">
jdbc:hsqldb:file:testdb;shutdown=true
</property>
<property name="hibernate.connection.driver_class">
org.hsqldb.jdbcDriver
</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password"></property>
<property name="hibernate.connection.pool_size">0</property>
<property name="hibernate.dialect">
org.hibernate.dialect.HSQLDialect
</property>
<property name="hibernate.show_sql">false</property>
<!-- "Import" the mapping resources here -->
<mapping class="sample.entity.Message"/>
</session-factory>
</hibernate-configuration>

build.xml

<project name="sample">
    <property file="build.properties"/>
    <property name="src" location="src"/>
    <property name="bin" location="bin"/>
    <property name="sql" location="sql"/>
    <property name="hibernate.tools"
              value="${hibernate.tools.home}${hibernate.tools.path}"/>
    <path id="classpath.base">
        <pathelement location="${src}"/>
        <pathelement location="${bin}"/>
        <pathelement location="${hibernate.home}/hibernate3.jar"/>
        <pathelement location="${slf4j.implementation.jar}"/>
        <fileset dir="${hibernate.home}/lib" includes="**/*.jar"/>
        <pathelement location="${hsql.home}/lib/hsqldb.jar"/>
  <fileset dir="./lib" includes="**/*.jar"/>
    </path>
<path id="classpath.tools">
    <path refid="classpath.base"/>
    <pathelement
            location="${hibernate.tools.home}/${hibernate.tools.lib.path}/commons-logging-1.0.4.jar"/>
    <pathelement
            location="${hibernate.tools}/freemarker.jar"/>
    <pathelement
            location="${hibernate.tools}/hibernate-tools.jar"/>
</path>
<taskdef name="htools"
         classname="org.hibernate.tool.ant.HibernateToolTask"
         classpathref="classpath.tools"/>
<target name="exportDDL" depends="compile">
    <mkdir dir="${sql}"/>
    <htools destdir="${sql}">
        <classpath refid="classpath.tools"/>
        <annotationconfiguration
                configurationfile="${src}/hibernate.cfg.xml"/>
        <hbm2ddl drop="true" outputfilename="sample.sql"/>
    </htools>
</target>
<target name="compile">
    <javac srcdir="${src}" destdir="${bin}" classpathref="classpath.base"/>
</target>
<target name="populateMessages" depends="compile">
    <java classname="sample.PopulateMessages" classpathref="classpath.base"/>
</target>
<target name="listMessages" depends="compile">
    <java classname="sample.ListMessages" classpathref="classpath.base"/>
</target>

【问题讨论】:

  • +1 详细问题。我遇到了同样的问题,查看您的 hibernate.cfg.xml 向我展示了我的问题。

标签: java hibernate annotations


【解决方案1】:

检查是否在 hibernate.cfg.xml 中定义了实体。

【讨论】:

    【解决方案2】:

    您可以通过在 Application .java 上添加以下注释来启用实体扫描 @EntityScan(basePackageClasses=YourEntityClassName.class)

    或者您可以在会话工厂中设置 packageToScan。 sessionFactory.setPackagesToScan(“com.all.entity”);

    【讨论】:

      【解决方案3】:

      添加后我的问题已解决
      sessionFactory.setPackagesToScan( 新字符串 [] { "com.springhibernate.model" }); 在 Spring Boot 最新版本 2.1.2 中测试了此功能。

      完整方法:

       @Bean( name="sessionFactoryConfig")
          public LocalSessionFactoryBean sessionFactoryConfig() {
      
              LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
      
              sessionFactory.setDataSource(dataSourceConfig());
              sessionFactory.setPackagesToScan(
                      new String[] { "com.springhibernate.model" });
      
              sessionFactory.setHibernateProperties(hibernatePropertiesConfig());
      
              return sessionFactory;
          }
      

      【讨论】:

        【解决方案4】:

        在 Spring Boot 应用程序的情况下使用下面的代码行。

        @EntityScan(basePackageClasses=YourClassName.class)

        【讨论】:

          【解决方案5】:

          在 Spring Boot Application 的情况下使用下面的代码行 添加 Spring Boot 主类 @EntityScan(basePackageClasses=YourClassName.class)

          【讨论】:

            【解决方案6】:

            使用 import javax.persistence.Entity; 而不是 import org.hibernate.annotations.Entity;

            【讨论】:

              【解决方案7】:

              如果您在 SpringBoot 应用程序中遇到此异常,即使实体已使用 Entity 注释进行注释,这可能是由于 spring 不知道在哪里扫描实体

              要明确指定包,请在下面添加

              @SpringBootApplication
              @EntityScan({"model.package.name"})
              public class SpringBootApp {...}
              

              注意:如果模型类位于SpringBootApplication注解类的同一个包或子包中,则无需显式声明EntityScan,默认会扫描

              【讨论】:

                【解决方案8】:

                我在切换到AnnotationSessionFactoryBean 时遇到了同样的问题。我之前用的是entity.hbm.xml

                我发现我的班级缺少以下注释,解决了我的问题:

                @Entity
                @Table(name = "MyTestEntity")
                @XmlRootElement
                

                【讨论】:

                  【解决方案9】:

                  在 hibernate.cfg.xml 中,请输入以下代码

                  <mapping class="class/bo name"/>
                  

                  【讨论】:

                    【解决方案10】:

                    您应该在您的AnnotationConfiguration 上致电.addAnnotatedClass(Message.class)

                    如果您希望自动发现您的实体,请使用 EntityManager (JPA)

                    (Reference)

                    更新:您似乎已在 hibernate.cfg.xml 中列出了该类。所以不需要自动发现。顺便说一句,试试javax.persistence.Entity

                    【讨论】:

                    • 不,OP 不应该这样做,实体在hibernate.cfg.xml 中声明。
                    • @Pascal Thivent 嗯,错过了那行。然后很奇怪,因为默认情况下Configuration.configure() 会查找 hibernate.cfg.xml
                    • 是的,我同意,这很奇怪。我希望事情会完全失败(找不到 .cfg.xml),而不是“部分”。激活日志记录可能会有所帮助,但我懒得设置 Ant 构建来重现 :)
                    • 大声笑,我发现了问题:)
                    • @Pascal Thivent 是吗? :)
                    【解决方案11】:

                    您的实体未正确注释,您必须使用@javax.persistence.Entity 注释。您可以使用 Hibernate 扩展 @org.hibernate.annotations.Entity 来超越 JPA 所提供的功能,但 Hibernate 注释不是替代品,而是一种补充。

                    所以把你的代码改成:

                    import javax.persistence.Entity;
                    import javax.persistence.GeneratedValue;
                    import javax.persistence.Id;
                    import javax.persistence.Table;
                    
                    @Entity
                    public class Message { 
                        ...  
                    }

                    参考文献

                    【讨论】:

                    • 啊,关于实体是强制性的注释对我来说是新的(我从未使用过休眠注释)。我发现了那篇文章(请参阅我的更新),但不确定它是否是答案 :) (+1)
                    • @Bozho 不能说注释,但我敢肯定,hibernate 注释一直是补充,而不是替代。那就为你的更新 +1。
                    • 我会测试的。我永远不会,永远不会抓住这个。
                    • @Stefan 好吧,这是一个恶性问题,我在与 Bozho 聊天后第 N 次扫描代码时发现了它。实际上,是写东西让我知道问题可能出在哪里。
                    • 但是如果作为实体的所需类来自另一个库怎么办?有没有办法使用@Entity
                    【解决方案12】:

                    如果需要自动发现类,则应在 .addAnnotatedClass(Class) 方法中添加所有实体文件。

                    使用此链接,它可能会有所帮助..

                    http://docs.jboss.org/hibernate/stable/core/api/org/hibernate/cfg/AnnotationConfiguration.html

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2011-11-28
                      • 2014-04-16
                      • 2012-12-04
                      • 2014-08-05
                      • 2012-06-17
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多