|
I came across this solution while searching
the Hibernate forum: http://hansonchar.blogspot.com/2005/06/why-use-beanlib-with-hibernate.html Beanlib, enables you to clone an object
graph, and you can configure it to do a deep clone or shallow clone. I struggled to get it working, with
limited documentation, but was very pleased once I got it working. Here’s some code: /** * Performs a deep
clone of a Project * * @param
projectId of Project to clone * @param user the
new Project owner * @return
projectId of new Project */ public long clone(long
projectId, User user) throws HibernateException {
Session session = HibernateUtil.getSession();
Project clonedProject = null;
try{
Project project = (Project)session.get(Project.class, projectId );
DetailedBeanPopulatable vetoer = new MyVetoer(session);
HibernateBeanReplicator replicator = new
Hibernate3BeanReplicator().initDetailedBeanPopulatable(vetoer);
clonedProject = (Project)replicator.copy(project);
clonedProject.setName(project.getName()+" [CLONE]");
clonedProject.setUserByUserCreated(user);
clonedProject.setUserByUserModified(user);
clonedProject.setDateCreated(new Date(System.currentTimeMillis()));
clonedProject.setLastModified(new Date(System.currentTimeMillis()));
session.save(clonedProject);
session = ManagedSessionContext.unbind(HibernateUtil.getSessionFactory());
session.getTransaction().commit();
} catch (Throwable ex){
HibernateUtil.rollbackTransaction(session);
throw new HibernateException(ex);
}
return clonedProject.getId(); } … public class MyVetoer implements
DetailedBeanPopulatable { private SessionFactory
sessionFactory; public MyVetoer(Session
session) {
this.sessionFactory = session.getSessionFactory(); } public boolean
shouldPopulate(String propertyName,
Object fromBean, Method readerMethod,
Object toBean, Method setterMethod) {
//Don’t want to create new instances of User and Keywordsource //So
populating the id field will stop Hibernate from saving a new instance. //it’s
a bit messy but it works…
if (fromBean instanceof User || fromBean instanceof Keywordsource)
return true;
if (Collection.class.isAssignableFrom(readerMethod.getReturnType()))
return true;
// Skip populating if it is an identifier property.
Class c = readerMethod.getDeclaringClass();
if (Enhancer.isEnhanced(c)) {
// figure out the pre-enhanced class
c = c.getSuperclass();
}
ClassMetadata classMetaData = sessionFactory.getClassMetadata(c);
return !classMetaData.getIdentifierPropertyName().equals(propertyName); } } From:
[email protected] [mailto:[EMAIL PROTECTED] On Behalf Of Noel Grandin You probably have a
recursive loop in there somewhere. On 5/4/06, Enrico
Goosen < [EMAIL PROTECTED]>
wrote: This is becoming really tricky. When I detach the object from the session, I can't access the
rest of the objects in the graph, since they may not have been loaded (Lazy
loading). I tried cloning as I traverse the non-detached object graph,
making sure to change the IDs of the clones and not the original, and it
appeared to be working, then I got an OutOfMemory error. *DOH* A solution must be close… From: [email protected]
[mailto:[email protected]]
On Behalf Of Noel Grandin
Yeah, you have to detach, or it maintains extra data
in the CGLIB-constructed objects that tell it that the object has an identity
in the database. On
5/4/06, Enrico Goosen <[EMAIL PROTECTED]>
wrote: The plot thickens… Is it really necessary to detach the object graph from the
session? I'm using the session-per-conversation pattern (long
conversation), because my Swing gui application doesn't work well Hibernate
session-per-request pattern. Setting the IDs to null is also a problem, because I'm using
long (primitive type) for the IDs. When I set the ID to -1, I get a NonUniqueObjectException. What to do…what to do… From: [email protected]
[mailto:[email protected]]
On Behalf Of Noel Grandin Hmmm, detaching the object will make it
"new" from hibernate's point of view. On
5/4/06, Enrico Goosen < [EMAIL PROTECTED]>
wrote: Is
it possible to clone and persist
an object graph in Hibernate? I've come across the org.hibernate.util.SerializationHelper which can be used to clone an object graph, but I don't think that it can be persisted, since its id's will be the same as the original object graph.
--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "CTJUG Forum" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/CTJUG-Forum -~----------~----~----~----~------~----~------~--~--- |
- [CTJUG Forum] Hibernate guru's Enrico Goosen
- [CTJUG Forum] Re: Hibernate guru's Noel Grandin
- [CTJUG Forum] Re: Hibernate guru's Enrico Goosen
- [CTJUG Forum] Re: Hibernate guru's Noel Grandin
- [CTJUG Forum] Re: Hibernate guru's Enrico Goosen
- [CTJUG Forum] Re: Hibernate guru's Bruce Stewart
- [CTJUG Forum] Re: Hibernate guru's Noel Grandin
- [CTJUG Forum] Re: Hibernate guru's Enrico Goosen
- [CTJUG Forum] Re: Hibernate guru's Bruce Stewart
