I want to persistent the detached object which have lazy loding collection of child objects (bag , cascade=all) with regenerate identifier.
(I want to do this for all object in my Webapp)
For example the database is like this.
PARENT TABLE
ID | NAME
-------------------
1 | hoge
CHILD TABLE
ID | P-SEQ | NAME
------------------
1 | 1 | foo
2 | 1 | bar
I load PARENT which id = 1 from first session, then close first session.
Then I modify parent.
Finally I persistent parent with regenerate identifier(insert to both parent and child) like this.
PARENT TABLE
ID | NAME
-------------------
1 | hoge
2 | hogehoge
CHILD TABLE
ID | P-SEQ | NAME
------------------
1 | 1 | for
2 | 1 | bar
3 | 2 | for
4 | 2 | bar
Now I could do this , but my source code is not perfect(I cannot support Map collection and etc) and too long.
So please let me know if someone knows more smart way.
Hibernate 3.2 / JAAV 5
My source code.
public void testDump() throws Exception{
SessionFactoryImpl f = (SessionFactoryImpl) sfac_;
Session s1 = f.getSession();
Transaction t1 = s1.beginTransaction();
Operation op = (Operation) s1.load(Operation.class, (long)257); //load parent
s1.evict(op);
t1.commit();
s1.close();
Session s2 = f.getSession();
Transaction t2 = s2.beginTransaction();
recreate(op,f,s2,new HashMap<Object, Object>());
s2.save(op);
t2.commit();
s2.close();
}
private void recreate(Object data,SessionFactoryImpl sFac,Session session, Map<Object, Object> checkMap) throws Exception {
if(checkMap.containsKey(data))return;
Class clazz = data.getClass();
if(data instanceof HibernateProxy){
clazz = clazz.getSuperclass();
}
ClassMetadata meta = sFac.getClassMetadata(clazz);
if ( meta.getIdentifierType().getClass() == LongType.class ){
meta.setIdentifier(data, new Long(0), EntityMode.POJO);
}else if ( meta.getIdentifierType().getClass() == IntegerType.class ){
meta.setIdentifier(data, new Integer(0), EntityMode.POJO);
}else{
meta.setIdentifier(data, new BigDecimal(0), EntityMode.POJO);
}
checkMap.put(data, data);
session.update(data);
for (String name: meta.getPropertyNames()) {
Type type = meta.getPropertyType(name);
if(type.isCollectionType()){
Collection v = (Collection) meta.getPropertyValue(data, name, EntityMode.POJO);
Collection nc = null;
if( type instanceof BagType){
nc = new ArrayList();
}else if( type instanceof ListType) {
nc = new ArrayList();
}else{
throw new NullPointerException();
}
for (Iterator it= v.iterator();it.hasNext();) {
Object object = it.next();
recreate(object,sFac,session,checkMap);
nc.add(object);
}
meta.setPropertyValue(data, name, nc, EntityMode.POJO);
}else if (type.isAssociationType()){
Object object = meta.getPropertyValue(data, name, EntityMode.POJO);
recreate(object,sFac,session,checkMap);
}
}
session.evict(data);
}
|