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

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进行归档)?

最佳答案

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

除非您在业务逻辑中的其他地方使用了归档逻辑,否则我不会走到最远,并用归档逻辑污染我完整的继承层次结构。只需使用两个会话,然后将存档的记录放在另一个模式,数据库或表中(该会话的映射取决于您)。

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

关于java - 用Java/Hibernate归档,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4603027/

10-14 11:46