如何让Hibernate只查询默认映射?

时间:2009-07-27 15:30:10

标签: java hibernate

我有一个实体类:

Cabbage.java

package womble;

public class Cabbage {
    private int id;
    // getters, setters, etc.
}

我已经映射到两个单独的数据库表,如下所示:

Cabbage.hbm.xml

<hibernate-mapping>
  <class name="womble.Cabbage"> <!-- Using the default entity and table name. -->
    <id name="id" unsaved-value="null">
      <generator class="native"/>
    </id>
  </class>
</hibernate-mapping>

CabbageBackup.hbm.xml

<hibernate-mapping>
  <class name="womble.Cabbage" entity-name="CabbageBackup" table="cabbage_backup">
    <id name="id">
      <generator class="assigned"/>
    </id>
  </class>
</hibernate-mapping>

我正在尝试检索上次保存的Cabbage实例,如下所示:

CabbageDao.java

package womble;

public class CabbageDao {
    Session session; // Hibernate session
    String GET_MAX_ID = "select max(id) from Cabbage";

    public getLastCabbage() {
        Object lastId = session.createQuery(GET_MAX_ID).uniqueResult();
        return session.load(Cabbage.class, lastId);
    }
}

这会引发NonUniqueResultException:“查询未返回唯一结果:2”

通过查看日志,Hibernate显然会查询这两个表,然后将结果连接在一起。

有没有办法让Hibernate只查询实体的默认映射? (也就是说,当我使用简单的类名时,专门防止它神奇地查询两个映射。)

我尝试使用上面的方法,使用标准API将Cabbage.class传递给#createCriteria(),以及字符串“Cabbage”,两者都从两个表中选择。我试图避免为“主”映射指定一个实体名称,因为在我的代码中有多个这样的类,我也必须修复它们之间的所有关系。

4 个答案:

答案 0 :(得分:2)

首先,Hibernate没有关于你的“默认”的概念 - 两者的映射都是平等的。就其而言。

您是否需要从备份表中访问旧卷心菜(不是我之前使用过的词组),或者您只是使用该表来存档旧数据?

如果是后者,则可能有更好的方法来实现相同的结果,例如使用数据库触发器。

答案 1 :(得分:1)

尝试在两个映射上使用实体名称,并指定您想要的内容。我相信那是该属性的契约。

答案 2 :(得分:0)

嗯,一个简单的答案(不一定是最好的答案)是使用.list()而不是.uniqueResult()带回最大ID的集合。然后,您可以将结果投入新的HashSet,让Java完成独特的工作。不优雅,但它会起作用。

public getLastCabbage() {
    Set lastIds = new HashSet(session.createQuery(GET_MAX_ID).list());
    // ignore the possibility of null; full steam ahead
    return session.load(Cabbage.class, lastIds.iterator().next());
}

答案 3 :(得分:0)

您可能会考虑为您执行此表修订的extensions to hibernate之一。我从未亲自使用过envers,但文档看起来很有趣。