HibernateQueryException 映射 class 与 Hibernate 版本 2.1.7 的复合键

HibernateQueryException with mapping a class with a composite key with Hibernate version 2.1.7

我正在维护一个旧软件,它使用 Hibernate 2.1.7c 版本(2004 年发布)作为具有 MySQL 数据库的对象关系映射。数据库 table 本身也很旧,它包含以下列:

remoteId bigint(20)
label    varchar(255)
locale   varchar(255)
PRIMARY KEY ('remoteId', 'locale')

我正在尝试创建一个新的 Class,它使用 Hibernate 映射文件来映射列。映射文件如下所示:

LocalizedNames.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
    <class name="package.package.LocalizedNames" table="localizednames">
        <composite-id>
            <key-property access="field" column="remoteId" name="remoteId" type="java.lang.Long"/>
            <key-property access="field" column="locale" name="locale" type="java.lang.String"/>
        </composite-id>
        <property column="label" name="label" not-null="true" access="field" type="java.lang.String"/>
    </class>
</hibernate-mapping>

我试着阅读旧的 Hibernate reference -book 一点,以了解它应该如何工作。书上也是这样说的:

Your persistent class must override equals() and hashCode() to implement composite identifier equality. 
It must also implements Serializable.

这就是 class 本身的样子:

public class LocalizedNames implements Serializable {
    private static final long serialVersionUID = 7526472295622776147L;
    private Long remoteId;
    private String label;
    private String locale;
    /*Getters and setters for each field*/

    @Override
    public boolean equals(Object o) {
        if (o == null) return false;
        if (getClass() != o.getClass()) return false;
        LocalizedNames obj = (LocalizedNames) o;

        if (obj.remoteId == this.remoteId &&
                obj.locale.equals(this.locale)) {
            return true;
        }

        return false;
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder(5, 25).
                append(label).
                toHashCode();
    }
}

好的,这就是 class 和 Hibernate 映射的实现。现在,当我尝试使用扩展 HibernateDaoSupport 的 Class 获取数据时,我得到的 HibernateQueryException 对我帮助不大。查询大致是这样的:

public class LocalizedNameDao extends BaseDao {
    public List findAllChoiceLocalizedNames(String locale) {
        List result = getHibernateTemplate().find("from LocalizedNames ln where ln.locale=?", locale);
        return result;
    }

 }

 public class BaseDao extends HibernateDaoSupport { ... }

我得到的堆栈跟踪是这样的:

org.springframework.orm.hibernate.HibernateQueryException: in expected: ln [from LocalizedNames ln where ln.locale=?]; nested exception is net.sf.hibernate.QueryException: in expected: ln [from LocalizedNames ln where ln.locale=?]
net.sf.hibernate.QueryException: in expected: ln [from LocalizedNames ln where ln.locale=?]
    at net.sf.hibernate.hql.FromParser.token(FromParser.java:102)
    at net.sf.hibernate.hql.ClauseParser.token(ClauseParser.java:87)
    at net.sf.hibernate.hql.PreprocessingParser.token(PreprocessingParser.java:123)
    at net.sf.hibernate.hql.ParserHelper.parse(ParserHelper.java:29)
    at net.sf.hibernate.hql.QueryTranslator.compile(QueryTranslator.java:149)
    at net.sf.hibernate.hql.QueryTranslator.compile(QueryTranslator.java:138)
    at net.sf.hibernate.impl.SessionFactoryImpl.getQuery(SessionFactoryImpl.java:295)
    at net.sf.hibernate.impl.SessionImpl.getQueries(SessionImpl.java:1571)
    at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1542)
    at net.sf.hibernate.impl.QueryImpl.list(QueryImpl.java:39)
    at org.springframework.orm.hibernate.HibernateTemplate.doInHibernate(HibernateTemplate.java:641)
    at org.springframework.orm.hibernate.HibernateTemplate.execute(HibernateTemplate.java:312)
    at org.springframework.orm.hibernate.HibernateTemplate.find(HibernateTemplate.java:631)
    at org.springframework.orm.hibernate.HibernateTemplate.find(HibernateTemplate.java:626)
    ... more stack trace ...

所以,有人知道我在这里做错了什么吗?我对旧的 Hibernate 版本不太熟悉,以前从未使用过复合键,所以它可能非常简单。异常及其给出的原因并没有给我太多信息去哪里看。问题似乎与 Hibernate 映射文件有关,但无法确定它的位置。

感谢大家的回答:)

设法解决了这个问题,就像我说的,这是一个简单的问题,只是缺少一些必要的配置:)