HBM.xml文件应该放在哪里?

4

我是一个Hibernate的新手,正在尝试使用嵌入式Derby数据库进行小型Hibernate示例。我在Eclipse中开发,没有使用Spring或Maven,也没有设置Web应用程序或应用服务器。如果项目变大,我可能会使用其中一些,但现在我只是想让这个示例正常工作。

我遇到的错误是:

Exception in thread "main" org.hibernate.MappingNotFoundException: resource: javabeat/net/hibernate/EmployeeInfo.hbm.xml not found

有时只需要:
Exception in thread "main" org.hibernate.MappingNotFoundException: resource: EmployeeInfo.hbm.xml not found

这是我的代码;我已经标记出错误似乎来自哪里 - Eclipse控制台显示异常并停止运行,它是逻辑上的地方:

package javabeat.net.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class JavaBeatHibernateExample
{
  public static void main(String args[]) throws Exception
  {

    configureDerbyEmbedded();

    Configuration cfg = new Configuration();
    cfg.addClass(javabeat.net.hibernate.EmployeeInfo.class);

    cfg.setProperty("hibernate.connection.driver_class", "org.apache.derby.jdbc.EmbeddedDriver");
    cfg.setProperty("hibernate.connection.password", "password");
    cfg.setProperty("hibernate.connection.url", "jdbc:derby:myEmbeddedDB;create=true");
    cfg.setProperty("hibernate.connection.username", "admin");
    cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.DerbyDialect");
    cfg.setProperty("cache.provider_class", "org.hibernate.cache.NoCacheProvider");

    // Exception almost certainly generated here.
    cfg.addResource("EmployeeInfo.hbm.xml");

    cfg.setProperty("hibernate.current_session_context_class", "thread");
    cfg.setProperty("hibernate.show_sql", "true");
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction transaction = session.beginTransaction();
    transaction.begin();
    EmployeeInfo employeeInfo = new EmployeeInfo();
    employeeInfo.setSno(1);
    employeeInfo.setName("KamalHasan");
    session.save(employeeInfo);
    transaction.commit();
    session.close();
  }

  private static void configureDerbyEmbedded() 
      throws ClassNotFoundException, IllegalAccessException, InstantiationException
  {
    Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
  }
}

我把Eclipse中的文件夹设置如下:
CarRepair
--src
----javabeat
------net
--------hibernate
----main
------resources
--------javabeat
----------net
------------hibernate

我有一个EmployeeInfo.hbm.xml文件,我把它放在以下位置: src/javabeat/net/hibernate main/resources/javabeat/net/hibernate main/resources
但我总是得到上述异常。在第一个位置,它只是说找不到XML文件;在后面两个位置,它在错误消息中在XML文件名之前加上了javabeat/net/hibernate。
该文件应该放在其他地方吗?还是我应该做些其他事情?
编辑:这可能与xml文件本身有关,导致误导性的错误消息吗?
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
    <hibernate-mapping>
        <class name="javabeat.net.hibernate.EmployeeInfo" table="Employee_Info">
            <id name="sno" column="sno" type="java.lang.Integer">
            </id>
            <property name="name" column="name" type="java.lang.String"/>
        </class>
    </hibernate-mapping>

Eclipse将源代码复制到二进制文件夹,因此这并没有实际帮助。 - arcy
2个回答

2

您的目录结构相当特殊。假设src是Eclipse中的源文件夹,它将复制所有非Java文件到类或bin目录(或您选择的编译类的目录名称),而EmployeeInfo.hbm.xml应直接位于src下,因为您告诉Hibernate从类路径的根目录加载它:

cfg.addResource("EmployeeInfo.hbm.xml");

如果您将它放在 main/resources 中,加载它的代码应该是:
cfg.addResource("main/resources/EmployeeInfo.hbm.xml");

为什么不使用自己的包层次结构,从而使用以下目录树:
src
  com
    rcook
      myapp

不行,在src下也不行。我仍然在异常信息中看到javabeat/net/hibernate/EmployeeInfo.hbm.xml的错误。 - arcy
这是因为您的代码中还有 cfg.addClass(javabeat.net.hibernate.EmployeeInfo.class)。这会要求 Hibernate 加载包 javabeat.net.hibernate 中的文件 EmployeeInfo.hbm.xml。选择您想要加载文件的方式,可以使用 addClass()addResource(),但不要同时使用两者。 - JB Nizet
好的,现在我明白了,我不应该从两个地方加载类,但这并不能解决这个错误,它明确表示找不到xml文件。我已经找到了一种方法使其工作,尽管我必须更改addResource语句。请看我的答案。 - arcy
抱歉 -- 如果我仔细记得告诉 Eclipse 进行清理和重建,它确实可以在 src 中工作。我可以像最初一样从 src 加载,如果我修改 addResource 语句,也可以从包位置加载。 - arcy

1

正如你所说,如果你不使用Maven,那么src/main/resources文件夹对于Eclipse项目来说就像任何其他文件夹一样。因此,只需将hbm文件复制到src文件夹下并删除"addClass"方法即可。


由于某些原因,将XML文件放入src文件夹中并不能解决问题。不过我找到了一种方法使它能工作,尽管我必须要修改上面的addResource方法,而且是的,我也必须删除addClass。我将写一个类似答案的东西。谢谢。 - arcy
非常抱歉,将其放入src确实可行 - 这一次我特别注意已经清理和重建了,上次可能是我错过了。谢谢 - 我将早期的答案标记为已接受,因为他最先回应了... - arcy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接