我有一个简单的对象,它只是通过休眠映射
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/