jacob
jacob

Reputation: 43

Archiving with Java/Hibernate

I have a simple object which is mapped simply by hibernate

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

Now, since my table is gettig quite huge (a couple of millions of entries), I decided to archive all of the entries I don't really need (the user might need them later on, by checking an option they schould be able to search the two tables the actual and the archived, but that's a thing I don't carre about yet and which will be done somewhere else).
So I've decided to keep my mapping files as simple as possible and also the way of converting an object (archived/non-archived) and use simple heritage

abstract class AbstractSimpleObject {
    // idem SimpleObject
}

class SimpleObject extends AbstractSimpleObject {

}

class SimpleObjectArchived extends AbstractSimpleObject {

}

I used union-subclass in my hibernate mapping and mapped SimpleObject to my old table, and SimpleObjectArchived to an identical table.
Upto now everything is fine, I can delete/create/update my objects. Now to the archiving:

In my SimpleObjectBusinessRules class I define a method archive:

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)
    }
}

I ommited all the try/catch/... I get an hibernate exception on saoDao.saveAll(...) org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session:[...]

Anyone any idea how to solve this problem? Or anyone already treated archiving with hibernate and has a better solution (or even a working solution how to archive with hibernate)?

Upvotes: 1

Views: 2854

Answers (1)

Falcon
Falcon

Reputation: 3170

I'd just create two sessions, one business-logic session and one archive-session, delete the object from the business logic session and save the converted object to the archive-session. You could implement an archive method in your DAO. This will spare you a lot of trouble.

I would not go as far as you and pollute my complete inheritance hierarchy with the archiving logic, unless it's used elsewhere in your business-logic (it probably isn't). Just use two session and put the archived records in another schema or database or table (the mapping for the session is up to you).

BTW: The exception occurs due to your mapping strategy. With a Union-Subclass-Mapping all the identifiers are stored within the same table, so the archive records and the business logic records are fed IDs from the same pool. You'd need a custom generation strategy to avoid that exception or change the mapping. But why bother with it when there's a more elegant solution to your problem (archiving session)?

Upvotes: 2

Related Questions