R
Ross Bamford
Hi,
Last night I was working on some ideas for my current project, but got
sidetracked while playing with the object persistence and came up with
an idea for a more general persistence system. I've not really given it
a *lot* of thought yet but would be interested in anyone's thoughts...
It's much the same as Serializable, but it doesn't require that objects
implement that (or any other) interface. Instead it simply maps instance
fields (whether public, protected, private, or package) directly to
database fields. All fields are stored, unless they're marked
'transient'. By default, the framework maps to database fields based on
the field's name, but this can be overriden by annotating that field
with a custom annotation (@serializeTo("fieldName") for example).
public Object loadObject(String id);
public void storeObject(String id, Object o);
When asked to store an object, it's a simple thing to loop through the
class and subclasses building an array of all instance vars with that
annotation. setAccessible on that array (obviously would need permission
but then it's a persistence system!), and get their values. You can then
store these however you like - Files, JDBC, whatever. Obviously you need
to keep members with their appropriate (super)class because they have to
be set again at load (and may be private).
When loading an object, you'd first need to load a header field that
graphs the hierarchy of the stored class, much like current
Serialisation. You can run through the serialVersionUIDs (by convention)
to check you've got the same classes, and then find all it's annotated
members in the same way and load 'em.
The persistence framework could allow mappings to be set up, e.g.
SomeClassName.data -> dataField to override the mapping of members to
fields, or a custom data format could be used.
So the programmer could make simple classes:
public class DataClass
{
private @serializeTo("data") String dataField; /* to: 'data' */
private int boolField; /* to: 'boolField' */
private transient AnotherClass anotherObject; /* Not stored */
}
and just throw instances at the storage mechanism.
So far I've thought of these problems:
Not-quite-backward compatibility, although it could treat existing
Serializable objects specially if required. It *would* respect those
classes stipulations about what *not* to store, however. It could invoke
their read/writeObject methods on it's own stream, and write that data
to support their custom stuff maybe.
+ Non-primitive fields would need some thought.
+ General backward compatibility would cause lots of issues.
I'm not sure what the benefits are, transparent storage of arbitrary
objects is attractive but not that far off right now. It's just that
something is telling me there's more in this ...
Cheers,
Ross
Last night I was working on some ideas for my current project, but got
sidetracked while playing with the object persistence and came up with
an idea for a more general persistence system. I've not really given it
a *lot* of thought yet but would be interested in anyone's thoughts...
It's much the same as Serializable, but it doesn't require that objects
implement that (or any other) interface. Instead it simply maps instance
fields (whether public, protected, private, or package) directly to
database fields. All fields are stored, unless they're marked
'transient'. By default, the framework maps to database fields based on
the field's name, but this can be overriden by annotating that field
with a custom annotation (@serializeTo("fieldName") for example).
public Object loadObject(String id);
public void storeObject(String id, Object o);
When asked to store an object, it's a simple thing to loop through the
class and subclasses building an array of all instance vars with that
annotation. setAccessible on that array (obviously would need permission
but then it's a persistence system!), and get their values. You can then
store these however you like - Files, JDBC, whatever. Obviously you need
to keep members with their appropriate (super)class because they have to
be set again at load (and may be private).
When loading an object, you'd first need to load a header field that
graphs the hierarchy of the stored class, much like current
Serialisation. You can run through the serialVersionUIDs (by convention)
to check you've got the same classes, and then find all it's annotated
members in the same way and load 'em.
The persistence framework could allow mappings to be set up, e.g.
SomeClassName.data -> dataField to override the mapping of members to
fields, or a custom data format could be used.
So the programmer could make simple classes:
public class DataClass
{
private @serializeTo("data") String dataField; /* to: 'data' */
private int boolField; /* to: 'boolField' */
private transient AnotherClass anotherObject; /* Not stored */
}
and just throw instances at the storage mechanism.
So far I've thought of these problems:
Not-quite-backward compatibility, although it could treat existing
Serializable objects specially if required. It *would* respect those
classes stipulations about what *not* to store, however. It could invoke
their read/writeObject methods on it's own stream, and write that data
to support their custom stuff maybe.
+ Non-primitive fields would need some thought.
+ General backward compatibility would cause lots of issues.
I'm not sure what the benefits are, transparent storage of arbitrary
objects is attractive but not that far off right now. It's just that
something is telling me there's more in this ...
Cheers,
Ross