Home > Archive > Java Help > January 2006 > Deserialization and repopulating transient fields
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Deserialization and repopulating transient fields
|
|
| PaulSchrum 2006-01-20, 9:57 pm |
| I am pretty new to Java. Using JDK 1.5 and netBeans 5.0 Beta.
I am having a problem which I think has to do with deserialzation and I
need advice on how to resolve my problem.
In class Clause I have several private fields which I persist:
private Phrase conjunction;
private Phrase subject;
private Phrase verb;
private Phrase object;
I also have an ArrayList which keeps these things in order:
transient private ArrayList<Phrase> collation
and a function which makes sure everything is in the right order:
updateCollation(){...}
I deserialize an instance of the class, then step into one of its
functions and find that collation is null. Of course, this is what I
would expect since I declare it as transient. But I need it to be
populated in order to use the instance elsewhere. The questions I have
below amount to, "what should I do about this?"
I can fix my problem by calling updateCollation(), but I do not know
how to call updateCollation() upon deserialization. I tried putting a
call to it in the no-parameter constructor, but it seems this is not
getting called when the object is being created from deserialization.
Is there a standard way to make updateCollation() run just after
Clause's fields have been deserialized but before the current instance
of Clause is through instantiating?
I realize that taking out the transient keyword would be one solution,
but I am still interested in how to call functions during
deserialization because I suspect I will need it again in the future.
Thanks,
- Paul
| |
| PaulSchrum 2006-01-20, 9:57 pm |
| More information on this.
I have found that the no-parameter constructor is being called at
deserialization time. The problem is that none of the Phrase fields
(subject, etc.) have been instantiated at that moment. When
updateCollation executes from the constructor, all of the fields are
null, so the collation is empty.
I still need advice on this. I am merely correcting my earlier
mistaken statement that the no-param constructor is not being called.
- Paul
| |
| Mark Thomas 2006-01-21, 9:57 pm |
| PaulSchrum wrote:
> I am pretty new to Java. Using JDK 1.5 and netBeans 5.0 Beta.
>
> I am having a problem which I think has to do with deserialzation and I
> need advice on how to resolve my problem.
>
> In class Clause I have several private fields which I persist:
>
> private Phrase conjunction;
> private Phrase subject;
> private Phrase verb;
> private Phrase object;
>
> I also have an ArrayList which keeps these things in order:
>
> transient private ArrayList<Phrase> collation
>
> and a function which makes sure everything is in the right order:
>
> updateCollation(){...}
>
> I deserialize an instance of the class, then step into one of its
> functions and find that collation is null. Of course, this is what I
> would expect since I declare it as transient. But I need it to be
> populated in order to use the instance elsewhere. The questions I have
> below amount to, "what should I do about this?"
>
> I can fix my problem by calling updateCollation(), but I do not know
> how to call updateCollation() upon deserialization. I tried putting a
> call to it in the no-parameter constructor, but it seems this is not
> getting called when the object is being created from deserialization.
>
> Is there a standard way to make updateCollation() run just after
> Clause's fields have been deserialized but before the current instance
> of Clause is through instantiating?
>
> I realize that taking out the transient keyword would be one solution,
> but I am still interested in how to call functions during
> deserialization because I suspect I will need it again in the future.
>
> Thanks,
>
> - Paul
>
Sounds like you need to use lazy initialization for the field - give it
a private accessor method which tests to see if the field is null, and
if so calls updateCollation(). Then wherever you have code that uses
collation (e.g. collation.iterator() ) replace with a call to the
accessor method first (e.g. getCollation().iterator() ).
Mark
| |
| PaulSchrum 2006-01-21, 9:57 pm |
| Mark,
Thanks for your reply. I was hoping that there was something native to
Deserialization that would be available for me to do, but it seems
there is nothing like that.
As I think things over, considering my data structure, I think the best
thing for me to do is add a "mendAfterDeserialization" function to all
my classes which I would call from the top level after everything has
been deserialized but before the .load function returns.
- Paul
| |
| Andrew McDonagh 2006-01-22, 3:57 am |
| PaulSchrum wrote:
> I am pretty new to Java. Using JDK 1.5 and netBeans 5.0 Beta.
>
> I am having a problem which I think has to do with deserialzation and I
> need advice on how to resolve my problem.
>
> In class Clause I have several private fields which I persist:
>
> private Phrase conjunction;
> private Phrase subject;
> private Phrase verb;
> private Phrase object;
>
> I also have an ArrayList which keeps these things in order:
>
> transient private ArrayList<Phrase> collation
>
> and a function which makes sure everything is in the right order:
>
> updateCollation(){...}
>
> I deserialize an instance of the class, then step into one of its
> functions and find that collation is null. Of course, this is what I
> would expect since I declare it as transient. But I need it to be
> populated in order to use the instance elsewhere. The questions I have
> below amount to, "what should I do about this?"
>
> I can fix my problem by calling updateCollation(), but I do not know
> how to call updateCollation() upon deserialization. I tried putting a
> call to it in the no-parameter constructor, but it seems this is not
> getting called when the object is being created from deserialization.
>
> Is there a standard way to make updateCollation() run just after
> Clause's fields have been deserialized but before the current instance
> of Clause is through instantiating?
>
> I realize that taking out the transient keyword would be one solution,
> but I am still interested in how to call functions during
> deserialization because I suspect I will need it again in the future.
>
> Thanks,
>
> - Paul
>
Like you say, it sounds like removing the 'transient' keyword may be
your best choice. However, there is another way....
http://java.sun.com/j2se/1.5.0/docs...rializable.html
Quoted from the API...
" Classes that require special handling during the serialization and
deserialization process must implement special methods with these exact
signatures:
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;
The writeObject method is responsible for writing the state of the
object for its particular class so that the corresponding readObject
method can restore it. The default mechanism for saving the Object's
fields can be invoked by calling out.defaultWriteObject. The method does
not need to concern itself with the state belonging to its superclasses
or subclasses. State is saved by writing the individual fields to the
ObjectOutputStream using the writeObject method or by using the methods
for primitive data types supported by DataOutput. "
| |
| Oliver Wong 2006-01-24, 7:06 pm |
|
"PaulSchrum" <paul.schrum@gmail.com> wrote in message
news:1137809865.987833.85150@g49g2000cwa.googlegroups.com...
>I am pretty new to Java. Using JDK 1.5 and netBeans 5.0 Beta.
>
> I am having a problem which I think has to do with deserialzation and I
> need advice on how to resolve my problem.
>
> In class Clause I have several private fields which I persist:
>
> private Phrase conjunction;
> private Phrase subject;
> private Phrase verb;
> private Phrase object;
>
> I also have an ArrayList which keeps these things in order:
>
> transient private ArrayList<Phrase> collation
>
> and a function which makes sure everything is in the right order:
>
> updateCollation(){...}
>
> I deserialize an instance of the class, then step into one of its
> functions and find that collation is null. Of course, this is what I
> would expect since I declare it as transient. But I need it to be
> populated in order to use the instance elsewhere. The questions I have
> below amount to, "what should I do about this?"
>
> I can fix my problem by calling updateCollation(), but I do not know
> how to call updateCollation() upon deserialization. I tried putting a
> call to it in the no-parameter constructor, but it seems this is not
> getting called when the object is being created from deserialization.
>
> Is there a standard way to make updateCollation() run just after
> Clause's fields have been deserialized but before the current instance
> of Clause is through instantiating?
>
> I realize that taking out the transient keyword would be one solution,
> but I am still interested in how to call functions during
> deserialization because I suspect I will need it again in the future.
>
> Thanks,
From http://java.sun.com/j2se/1.5.0/docs...ializable.html:
<quote>
Classes that require special handling during the serialization and
deserialization process must implement special methods with these exact
signatures:
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;
[...]
The readObject method is responsible for reading from the stream and
restoring the classes fields. It may call in.defaultReadObject to invoke the
default mechanism for restoring the object's non-static and non-transient
fields. The defaultReadObject method uses information in the stream to
assign the fields of the object saved in the stream with the correspondingly
named fields in the current object. This handles the case when the class has
evolved to add new fields. The method does not need to concern itself with
the state belonging to its superclasses or subclasses. State is saved by
writing the individual fields to the ObjectOutputStream using the
writeObject method or by using the methods for primitive data types
supported by DataOutput.
</quote>
- Oliver
| |
| PaulSchrum 2006-01-25, 9:58 pm |
| Oliver and Andrew,
This is just a quick note to thank you for your help. I had read (or
at least skimmed) the docs you cite, but it did not occur to me that
what they were talking about was the same thing I was asking about. So
again, thanks.
- Paul
|
|
|
|
|