-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 
Author Message
 Post subject: Newifying an object
PostPosted: Wed Oct 15, 2003 5:02 pm 
Newbie

Joined: Wed Oct 15, 2003 4:31 pm
Posts: 17
Howdy,

Occasionally I have a need to save a new instance of a persisted class. For example, if there is a change to a name, I need to retain the original record that the instance was rehydrated from and set the current insteance to act as if it's new (do aninsert, allocate a new primary key).

What seemed the best way to do this was to grab the ClassMetaData for the target instance and use the setIdentifier(instance, null) call to clear the identifier. As I understnad things, when the object does eventually get saved/updated, hibernate will see the id is null and start an insert and allocate a new key.

Of course, nothing is that easy. In this case, when I do this, I get an IllegalArgumentException which is rethrown as a hibernate exception "Null value was assign to a property of primative type setter SOpen.common.dao.DAOBase.primaryKey".

Is this the best way to "newify" an existing instance? If not, are there better ones? Also, are their any things to watch out for if I try to "newify" a brand new instance of a class (one that has not yet been persisted?).

Thanks for any pointers/thoughts on this one,

Gerry


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 15, 2003 5:08 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Could you utilize a clone() override? This kind of thing is tailor-made for cloning.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 15, 2003 5:35 pm 
Newbie

Joined: Wed Oct 15, 2003 4:31 pm
Posts: 17
steve wrote:
Could you utilize a clone() override? This kind of thing is tailor-made for cloning.


The problem is that there could easily be other references out there to the modified instance. If I did a clone, I'd have to update any/all other refs to that object. Using the idea of just "newifying" an instance makes it transparent to any refers to the instance.


Top
 Profile  
 
 Post subject: other way around?
PostPosted: Wed Oct 15, 2003 6:16 pm 
Senior
Senior

Joined: Sun Aug 31, 2003 3:14 pm
Posts: 151
Location: Earth (at the moment)
Quote:
I need to retain the original record that the instance was rehydrated from and set the current insteance to act as if it's new (do aninsert, allocate a new primary key).


Quote:
Could you utilize a clone() override? This kind of thing is tailor-made for cloning


I think you can do what Steve suggests by reversing how you look at it.
Instead of "newifying" the current version, clone it before you change the "immutable" properties and make the clone the "new" instance and allow your "current" instance to be changed and then all of the references to it would still be correct. You can then insert the clone as a new record with the old data.


Top
 Profile  
 
 Post subject: Re: other way around?
PostPosted: Thu Oct 16, 2003 8:27 am 
Newbie

Joined: Wed Oct 15, 2003 4:31 pm
Posts: 17
DavidNDuffy wrote:
I think you can do what Steve suggests by reversing how you look at it.
Instead of "newifying" the current version, clone it before you change the "immutable" properties and make the clone the "new" instance and allow your "current" instance to be changed and then all of the references to it would still be correct. You can then insert the clone as a new record with the old data.


It's something to consider. However, I would like to know if it's possible to clear the ID on a previously persisted object to force it to behave like a "new" object - depending on the practicality of that and the work involved, I could look into which methods make most sense in this case :-)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 16, 2003 8:37 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 7:19 pm
Posts: 2364
Location: Brisbane, Australia
Try nulling the id. Assuming your not using 'assigned' generator then a new Id will be assigned and a new tuple created.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 16, 2003 8:56 am 
Newbie

Joined: Wed Oct 15, 2003 4:31 pm
Posts: 17
david wrote:
Try nulling the id. Assuming your not using 'assigned' generator then a new Id will be assigned and a new tuple created.


I've tried that wil code like:

ClassMetadata snapshotMeta =sessionFactory.getClassMetadata(newSnapshot.getClass());
snapshotMeta.setIdentifier(newSnapshot, null);

And when the code runs, I get an exception like:

[java] java.lang.IllegalArgumentException
[java] at sun.reflect.GeneratedMethodAccessor13.invoke(Unknown Source)
[java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[java] at java.lang.reflect.Method.invoke(Method.java:324)
[java] at net.sf.hibernate.util.ReflectHelper$Setter.set(ReflectHelper.java:45)
[java] at net.sf.hibernate.persister.AbstractEntityPersister.setIdentifier(AbstractEntityPersister.java:287)
[java] at SOpen.common.dao.VDAORoot.newifySnapshot(VDAORoot.java:145)
[java] at SOpen.common.dao.VDAORoot.recordSnapshot(VDAORoot.java:214)
[java] at local.gerry.SPMTest.main(SPMTest.java:80)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
[java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[java] at java.lang.reflect.Method.invoke(Method.java:324)
[java] at org.apache.tools.ant.taskdefs.ExecuteJava.run(ExecuteJava.java:208)
[java] at org.apache.tools.ant.taskdefs.ExecuteJava.execute(ExecuteJava.java:150)
[java] at org.apache.tools.ant.taskdefs.Java.run(Java.java:443)
[java] at org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:163)
[java] at org.apache.tools.ant.taskdefs.Java.execute(Java.java:108)
[java] at org.apache.tools.ant.Task.perform(Task.java:341)
[java] at org.apache.tools.ant.Target.execute(Target.java:309)
[java] at org.apache.tools.ant.Target.performTasks(Target.java:336)
[java] at org.apache.tools.ant.Project.executeTarget(Project.java:1339)
[java] at org.apache.tools.ant.Project.executeTargets(Project.java:1255)
[java] at org.apache.tools.ant.Main.runBuild(Main.java:609)
[java] at org.apache.tools.ant.Main.start(Main.java:196)
[java] at org.apache.tools.ant.Main.main(Main.java:235)
[java] rethrown as
[java] net.sf.hibernate.PropertyAccessException: Null value was assigned to a property of primitive type setter of SOpen.common.dao.DAOBase.primaryKey
[java] at net.sf.hibernate.util.ReflectHelper$Setter.set(ReflectHelper.java:64)
[java] at net.sf.hibernate.persister.AbstractEntityPersister.setIdentifier(AbstractEntityPersister.java:287)
[java] at SOpen.common.dao.VDAORoot.newifySnapshot(VDAORoot.java:145)
[java] at SOpen.common.dao.VDAORoot.recordSnapshot(VDAORoot.java:214)

which has thrown me a bit (and what started my windmill tilting session :-)

Gerry


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 16, 2003 9:22 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Is your identifier on that class a java primitive type? If so, obviously, setting to null is not going to work. Instead you really should be setting to whatever is equivalent "unsaved-value" is. For primitive ids, this is typically zero.

Quote:
Using the idea of just "newifying" an instance makes it transparent to any refers to the instance.

Huh? You know your model better than us, but as you did not post anything regarding it I have nothing to go off of other than all the possibilities. Say the class you are attempting to "newify" (although now this is starting to sound an awful lot like archiving) participates in a collection association with some other entity. Generating a new instance in this manner will leave that other entity with references to both the new and old "newified" entity. Hardly transparent to the app.

But see thats the nice thing about cloning (actually I rarely use clone(), rather some business method like generateCopy()); you get to control what data and associations get transferred.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 19, 2003 7:25 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Note that Hibernate 2.1 provides the replicate() method for this kind of stuff.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 20, 2003 9:24 am 
Newbie

Joined: Wed Oct 15, 2003 4:31 pm
Posts: 17
gavin wrote:
Note that Hibernate 2.1 provides the replicate() method for this kind of stuff.


Very interesting - are there any docs on what it does (or even a quick summary). I found the api docs, but it's a one liner and I'm not quite sure what happens when you invoke it.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Nov 09, 2003 7:30 pm 
Beginner
Beginner

Joined: Sat Aug 30, 2003 1:36 am
Posts: 47
Location: Calgary, AB
So what does happen on replicate? Are all of the collections and what not also set to be duplicated?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.