Grokbase Groups Cayenne user May 2006
FAQ
I'm writing a swing app based on the NetBeans platform. I tried to
serialize a bean containing cayenne generated beans and got the
following result (please excuse the lenght):

Serializable class cayennedata.OrganizationType does not declare
serialVersionUID field. Encountered while storing:
[org.openide.windows.TopComponent$Replacer, advancedsearch.Testing,
java.lang.Integer, java.lang.Number] See also
http://www.netbeans.org/issues/show_bug.cgi?id=19915
Serializable class cayennedata.generated._OrganizationType does not
declare serialVersionUID field. Encountered while storing:
[org.openide.windows.TopComponent$Replacer, advancedsearch.Testing,
java.lang.Integer, java.lang.Number, cayennedata.OrganizationType] See
also http://www.netbeans.org/issues/show_bug.cgi?id=19915
Serializable class org.objectstyle.cayenne.CayenneDataObject does not
declare serialVersionUID field. Encountered while storing:
[org.openide.windows.TopComponent$Replacer, advancedsearch.Testing,
java.lang.Integer, java.lang.Number, cayennedata.OrganizationType,
cayennedata.generated._OrganizationType] See also
http://www.netbeans.org/issues/show_bug.cgi?id=19915
Serializable class org.objectstyle.cayenne.ObjectId does not declare
serialVersionUID field. Encountered while storing:
[org.openide.windows.TopComponent$Replacer, advancedsearch.Testing,
java.lang.Integer, java.lang.Number, cayennedata.OrganizationType,
cayennedata.generated._OrganizationType,
org.objectstyle.cayenne.CayenneDataObject] See also
http://www.netbeans.org/issues/show_bug.cgi?id=19915

I have a couple of questions about this.
First, is there any special reason the templates, the DataObject and
the ObjectId class don't have a serialVersionUID?
Second, is it possible at all to successfuly serialize a class
representing a database entity? Won't the serialization algorithm get
just about the entire database, following the bean getters?

I'd very much appreciate a comment on the topic, as well as a prod in
the right direction concerning cayenne DataObject serialization.
Should I be looking at decode/encodeXML?

t.n.a.

Search Discussions

  • Andrus Adamchik at May 18, 2006 at 2:17 pm

    On May 18, 2006, at 6:54 AM, Tomi NA wrote:

    I have a couple of questions about this.
    First, is there any special reason the templates, the DataObject and
    the ObjectId class don't have a serialVersionUID?
    We should probably add serialVersionUID to all serializable classes
    (and somehow add it to cgen templates) - this may be an improvement
    to the future versions. But the JVM should not throw an exception
    when it is absent either. So are you getting some kind of warning, or
    is this an exception?

    Second, is it possible at all to successfuly serialize a class
    representing a database entity?
    Absolutely. Serialization of DataObjects worked since Cayenne 1.0.
    The easiest way is to serialize the entire DataContext; if you
    serialize individual objects, you will have to manually reattach them
    to the context on deserialization (e.g. by calling 'localObject').

    Won't the serialization algorithm get
    just about the entire database, following the bean getters?
    No, Java serialization does not use getters, it serializes fields
    directly. However IIRC Java bean serialization does - so this can be
    a problem.
    I'd very much appreciate a comment on the topic, as well as a prod in
    the right direction concerning cayenne DataObject serialization.
    Should I be looking at decode/encodeXML?
    If you don't care about the format, Java binary serialization should
    be more efficient than XML.

    Andrus
  • Tomi NA at May 18, 2006 at 2:59 pm

    On 5/18/06, Andrus Adamchik wrote:
    On May 18, 2006, at 6:54 AM, Tomi NA wrote:

    I have a couple of questions about this.
    First, is there any special reason the templates, the DataObject and
    the ObjectId class don't have a serialVersionUID?
    We should probably add serialVersionUID to all serializable classes
    (and somehow add it to cgen templates) - this may be an improvement
    to the future versions. But the JVM should not throw an exception
    when it is absent either. So are you getting some kind of warning, or
    is this an exception?
    It is just a warning, but it seems that the serialization process
    fails as I get null values when I deserialize. I thought the missing
    UID might be the reason.
    Second, is it possible at all to successfuly serialize a class
    representing a database entity?
    Absolutely. Serialization of DataObjects worked since Cayenne 1.0.
    The easiest way is to serialize the entire DataContext; if you
    serialize individual objects, you will have to manually reattach them
    to the context on deserialization (e.g. by calling 'localObject').
    Won't the serialization algorithm get
    just about the entire database, following the bean getters?
    No, Java serialization does not use getters, it serializes fields
    directly. However IIRC Java bean serialization does - so this can be
    a problem.
    Hmm...I'm sorry to hear that. The problem is, I have a panel and a
    bean (presenter, model, if you will) and I bind them using jgoodies
    binding. Some of the bean fields are cayenne DataObjects. I have these
    kinds of panels all over the app, but I need to serialize just a
    couple of them: the point is to save a part of the frame (panel)
    state.
    Now, to the fields-bean properties issue...If I deserialized the
    entire context, as you suggest, what would that do for me in terms of
    (de)serializing my own bean containing private fields with their
    respective public get/set pairs?
    How should I go about serializing/deserializing such objects? All I
    have at my disposal right now is a stream to which I can write to or
    read from, depending on whether I'm serializing or deserializing. I'm
    not clear on what happens when I write an object to such a stream, no
    matter the fact I have a serialized DataContext.
    I'd very much appreciate a comment on the topic, as well as a prod in
    the right direction concerning cayenne DataObject serialization.
    Should I be looking at decode/encodeXML?
    If you don't care about the format, Java binary serialization should
    be more efficient than XML.
    I couldn't care less. :)

    t.n.a.
  • Andrus Adamchik at May 18, 2006 at 3:59 pm

    On May 18, 2006, at 10:58 AM, Tomi NA wrote:

    Hmm...I'm sorry to hear that. The problem is, I have a panel and a
    bean (presenter, model, if you will) and I bind them using jgoodies
    binding. Some of the bean fields are cayenne DataObjects. I have these
    kinds of panels all over the app, but I need to serialize just a
    couple of them: the point is to save a part of the frame (panel)
    state.
    Ok, then serializaing the entire context is indeed inappropriate.
    Just serialize the objects (note that 'objectContext' is a transient
    field, so a serialized object won't drag a DC with it).
    How should I go about serializing/deserializing such objects? All I
    have at my disposal right now is a stream to which I can write to or
    read from, depending on whether I'm serializing or deserializing. I'm
    not clear on what happens when I write an object to such a stream, no
    matter the fact I have a serialized DataContext.
    A simple trick would be to use thread-bound DC and create
    "readResolve" method in a custom DO superclass that reattaches itself
    to the thread context (or rather returns a substitute object local to
    the current DC):

    private Object readResolve() throws ObjectStreamException {
    DataContext dc = DataContext.getThreadDataContext();
    return dc == null ? this : dc.localObject(getObjectId(), this);
    }

    Andrus
  • Tomi NA at May 20, 2006 at 9:25 am

    On 5/18/06, Andrus Adamchik wrote:

    A simple trick would be to use thread-bound DC and create
    "readResolve" method in a custom DO superclass that reattaches itself
    to the thread context (or rather returns a substitute object local to
    the current DC):

    private Object readResolve() throws ObjectStreamException {
    DataContext dc = DataContext.getThreadDataContext();
    return dc == null ? this : dc.localObject(getObjectId(), this);
    }
    This brought me closer to the solution, but I'm not there yet.
    Here's what I did.
    My dc is in a public static field instead of the current thread - I'm
    not sure I can depend on always being in the same thread and I'd like
    to use the same dc during the runtime of the app.
    I've extended CayenneDataObject along the lines you suggested:

    public class SerializableCayenneDataObject extends CayenneDataObject {

    public SerializableCayenneDataObject() {
    }

    private Object readResolve() throws ObjectStreamException {
    DataContext dc = Misc.context; // not from the current thread
    return dc == null ? this : dc.localObject(getObjectId(), this);
    }
    }

    I've regenerated the generated superclasses so that they extend the
    SerializableCayenneDataObject instead of CayenneDataObject.
    Alas, the breakpoint I placed inside the readResolve method never gets
    called and I still get an object with null values for all fields
    instead of the object I stored.

    I tested then if the readResolve code would work anyway and included
    it into the readExternal() deserialization method. This is what it
    looks like:

    public void readExternal(ObjectInput in) throws IOException,
    ClassNotFoundException {
    try {
    MyEntityDataObject medo = (MyEntityDataObject)in.readObject();
    medo = (MyEntityDataObject)
    Misc.dataContext.localObject(medo.getObjectId(), medo);
    System.out.println(medo.getName());
    } catch (Exception ex) {
    ex.printStackTrace();
    }
    }

    public void writeExternal(ObjectOutput out) throws IOException {
    out.writeObject((MyEntityDataObject)MyEntityDataObject.dohvatiPopis(Misc.dataContext).get(0));
    }

    Anyway, this works. I get a medo object with the information I stored
    using writeExternal. What I really need now is a way to make the
    DataContext.localObject call transparent i.e. have it called
    internally in my dataObject by extending my custom DataObject. Can
    anyone tell me what I did wrong?

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupuser @
categoriescayenne
postedMay 18, '06 at 10:55a
activeMay 20, '06 at 9:25a
posts5
users2
websitecayenne.apache.org

2 users in discussion

Tomi NA: 3 posts Andrus Adamchik: 2 posts

People

Translate

site design / logo © 2022 Grokbase