1

我有一个简单的对象,它通过休眠简单地映射

class SimpleObject {
   private int id;
   private String textA;
   private String textB;
   private Date date;
   private Status status;
   //+getters/setters/other stuff
}

现在,由于我的表格非常庞大(几百万个条目),我决定归档所有我并不真正需要的条目(用户可能稍后需要它们,通过检查他们应该能够的选项搜索实际和存档的两个表,但这是我还不关心的事情,它将在其他地方完成)。
所以我决定让我的映射文件尽可能简单,以及转换对象(存档/非存档)的方式并使用简单的遗产

abstract class AbstractSimpleObject {
    // idem SimpleObject
}

class SimpleObject extends AbstractSimpleObject {

}

class SimpleObjectArchived extends AbstractSimpleObject {

}

我在休眠映射中使用了union-subclass并将 SimpleObject 映射到我的旧表,并将 SimpleObjectArchived 映射到相同的表。
到目前为止一切都很好,我可以删除/创建/更新我的对象。现在归档:

在我的 SimpleObjectBusinessRules 类中,我定义了一个方法归档:

class SimpleObjectBusinessRules {
    // the daos for the SimpleObject and the SimpleObjectArchived both using HibernateDaoSupport
    SODao soDao;
    SOADao soaDao;

    //...
    //you can say which objects to archive by some criterias
    public void archive(Map<String,Object> pCrit) {
        List<SimpleObject> lSOs = soDao.getByCriteria(pCrit);
        //I wrote myself a converter (based on dozer)
        List<SimpleObjectArchived> lSOAs = Converter.convertToSOA(lSOs);
        soDao.deleteAll(lSOs);
        soaDao.saveAll(lSOAs); //based on getHibernateTemplate().saveOrUpdateAll(pEntities)
    }
}

我省略了所有的 try/catch/... 我得到一个休眠异常saoDao.saveAll(...) org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session:[...]

有人知道如何解决这个问题吗?或者任何人已经用hibernate处理归档并且有更好的解决方案(或者甚至是如何使用hibernate归档的工作解决方案)?

4

1 回答 1

2

我只需创建两个会话,一个业务逻辑会话和一个存档会话,从业务逻辑会话中删除对象并将转换后的对象保存到存档会话。你可以在你的 DAO 中实现归档方法。这将为您省去很多麻烦。

我不会像你那样用归档逻辑污染我的完整继承层次结构,除非它在你的业务逻辑的其他地方使用(它可能不是)。只需使用两个会话并将存档记录放在另一个模式或数据库或表中(会话的映射取决于您)。

顺便说一句:由于您的映射策略而发生异常。使用联合子类映射,所有标识符都存储在同一个表中,因此归档记录和业务逻辑记录是来自同一个池的 ID。您需要自定义生成策略来避免该异常或更改映射。但是,当您的问题(归档会话)有更优雅的解决方案时,为什么还要打扰它呢?

于 2011-01-05T10:35:32.763 回答