You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by Niclas Hedhman <ni...@hedhman.org> on 2004/09/28 14:13:37 UTC
Persistence in Merlin, Part One [long]
Gang,
I, Andreas and Peter Neubauer was chatting yesterday about a standard
persistence mechanism in Merlin.
This Part One will provide an introduction to JDO to those who have no
previous experience, and look at the basic principles involved.
A second Part will cover what are the concerns regarding classloading,
hot-deployments and reloading of components using persistence.
A third Part will cover the implementation of such system, and how to use it.
Perhaps I'll skip this part and just do it, together with some examples.
Introduction to JDO.
====================
Personally, I am favour JDO very much, since I think it has a fairly clean API
and is a proven concept with many implementations of various quality.
There is an argument to put an additional layer on top, so we could map
additional persistence strategies to tool bag.
The only additional system I can see in the near future would be Hibernate,
and I am wondering if it isn't better to make a JDO styled (obs not JDO,
since that implies a lot of compatibility constraints) wrapper around
Hibernate instead.
JDO is trying to promise "transparent persistence" in that classes that can be
persisted doesn't normally need any special programming. Any POJO *should*
do, but there are some restrictions (see below).
Now, JDO looks roughly like this (ascii art warning);
+---------------------------+
| PersistenceManagerFactory |
+---------------------------+
1 +-------------+
| +-----------1| Transaction |
| | +-------------+
* 1
+--------------------+ +--------+
| PersistenceManager |1--------*| Extent |
+--------------------+ +--------+
1 1
| | +-------+
| +-----------*| Query |
* +-------+
+--------------------+
| PersistenceCapable |
+--------------------+
The PersistenceManagerFactory is the bootstrap singleton, which I think we
don't need to engage at all.
The PersistenceManager is the central guy in the system. In our terms it will
be a Service, and the implementation comes from the JDO implementation
vendor.
The PersistenceCapable interface are implemented for classes to be storeable
with a primary key, both to allow queries as well as being decomposed when
referenced by other PersistenceCapable objects.
Transaction is an interface with methods as expected.
Query is an interface with methods as expected.
Extent is a logical view of all the objects of a particular class that exists
in the store. (don't worry about this for a second)
Now, the PersistenceCapable interface is the marker for whether a class should
be decomposed into its fields or saved serialized when stored. However, JDO
doesn't require you to implement this interface yourself in the source code.
Instead, the compiled class will be modified at bytecode level to include
this. This is done by a tool called the JDO Enhancer, which is supplied by
the JDO implementation vendor. However, there is a requirement by JDO that
all JDO Enhancers are binary compatible.
Furthermore, since classes may have public, package protected or protected
fields/members, the JDO Enhancer will need to modify the bytecodes for all
classes that access these fields as well.
Restrictions placed on PersistenceCapable classes;
* A No-Arg constructor, but not necessarily public.
* PersistenceCapable can inherit from non-persistence capable classes, but
there are some exceptions;
- Not from some native implemented classes, such as Thread and Socket.
- The fields in the superclass will not be persisted.
- All classes in the inheritence tree must use the same JDO identity type
or, if using application identity type, then they must use the same identity
class.
* Immutable datatypes supported required by spec; All primitives and their
wrappers, String, BigInteger, BigDecimal, Number and Locale.
* Mutable datatypes supported required by spec; Date and HashSet. (This I a
bit odd, but luckily many implementations support the entire Collections
API.)
* Arrays are a troubled chapter. Since one can't subclass or replace arrays,
JDO impls can't detect when new values are written into the array. So one
need to either assign the array field/member again, or mark the array dirty
through an JDOHelper utility class.
* Fields of non-PersistenceCapable classes and user-defined interfaces will
be handled in an implementation dependent manner, most impls seems to
serialize and not decomposed even if the object assigned to the field is
PersistenceCapable.
Yes these are restrictions, but are they unbearable. IMHO, after doing a
couple of apps is that they are "reasonable".
Ok, let's continue;
Just like EJBs, JDO can callback to the object instance for certain
operations, jdoPostLoad, jdoPreStore, jdoPreDelete, jdoPreClear.
However, unlike EJBs, this is optional, and done by implementing an interface
called InstanceCallbacks.
I'm skipping the explaination of JDO identity types and identity classes, for
now, as I feel it is not important in this context (maybe a lot of the above
is not important in the context as well, but...)
JDO requires Metadata for the PersistenceCapable classes. That must be defined
in XML according to a DTD.
There are basically three purposes for this metadata;
* Identification of PersistenceCapable classes.
* Override of default JDO behaviour, such as linking fields to existing DB
schemas.
* Provision of information that the implementation can not figure out from
reflecting the class, i.e. JDO impl extensions.
The amount of metadata that can be defined is massive, but not very much is
required.
The JDO implementation I use, have javadoc tags to place the metadata in the
source, and a tool generates the XML. I am not sure, whether this is a
standard or Solarmetrics own construct.
The XML metadata can either be one file for the entire application, in which
case it must be located as a resource "package.jdo". Or it can be placed in
the same package as the PersistentCapable class and named "<classname>.jdo".
The packaging requires the file to be reachable by the class' classloader.
I think this concludes the principals of JDO.
There are so much features in JDO, and I don't think it is appropriate to get
into them here. Instead, I would like to conclude;
I think that the whole JDO API/SPI can be 'considered' services in the Merlin
component model, and that we can wrap JDO implementations as Merlin
components, similarily to the Jetty wrapping done for the Http facility.
I also don't think that the Persistence mechanism is a Facility, i.e. it
doesn't need to reach the Merlin composition model. And we should create a
Magic plugin that creates the JDO metadata as well as running the bytecode
enhancer (which I assume an OSS version is available).
And I strongly suspect that some solid classloader analysis and deployment
strategy is required. Perhaps leading to a proposal for "System Services",
which are not facilities.
Cheers
Niclas
--
+------//-------------------+
/ http://www.bali.ac /
/ http://niclas.hedhman.org /
+------//-------------------+
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org