I'll do my best to recap the things that happened in the hackathon a
couple days ago as well as recap how the alternate backend work is
coming along in general. Others can chime in if I miss something or get
something wrong.
Once again it was Anil Gangolli, Allen Gilliland, Mitesh Meswani, and
Craig Russell who met on sept 13th to discuss the datamapper business
object persistence abstraction. This time we had a little less time to
work and spent a fair amount of the time working through some
discussions about the build process and where configs should be and how
to get them there.
We decided that the build process for the business layer needed some
tweaking to better allow Craig and Mitesh to do custom work for building
the datamapper and generating things like jdo mapping files. Allen
agreed to take a look at this.
We also found that there were some complexities with the unit testing
process which were making things slower and harder than was needed, so
Allen and Mitesh were going to work together to try and clean that up a
little bit. The main goals were to make it possible to run the tests
without having to do a full rebuild and recompile and also to see if
there is a way to enable the business layer tests to only require
building of the business layer and its tests.
We also spent a little time talking about requirements for JDO and JPA
and found that JDO should be fine working with Rollers current build
setup, but a JPA implementation may require jdk 1.5. Mitesh agreed to
double check this and report on it for sure.
Current status on the work overall:
We all agreed that the datamapper strategy should work and is worth
pursuing, so Craig is continuing down that path and flushing out the
rest of the code for that in the sandbox.
Craig is already onboard and working on a JDO specific implementation
via the datamapper, and Mitesh Meswani also joined the hackathons and
has offered to work on a JPA specific implementation also using the
datamapper. So we should have both a JDO and JPA backend when it's all
said an done.
Now that we've worked through some of the initial design issues and have
fixed up most of the remaining obstacles in the build process we mostly
leaving the rest to Craig and Mitesh to flush out the rest of the code.
Some of the issues/items that have come up are things that affect the
main src tree of Roller, so I'll talk about how/when we would address
those in another email.
That's pretty much it. I have a few more comments and updates inline
below ...
Craig L Russell wrote:
Anil Gangolli, Allen Gilliland, Mitesh Meswani, and Craig Russell met
yesterday to discuss the datamapper business object persistence abstraction.
We reviewed and checked in the Datamapper code that Craig put together.
Some updates from the session were also checked in; other code that was
reviewed still needs to be checked in. We checked the code into the
Roller 3.0 branch.
We looked at the DatamapperRollerImpl and refactored it a bit. Most
subclasses of DatamapperRollerImpl would use the Datamapper manager
classes directly so we eliminated the indirection from getXXXManager. A
subclass of DatamapperRollerImpl, e.g. JDORollerImpl, would have to
implement the getXXXManager method and not the createXXXManager.
The current code assumes that a Datamapper transaction is begun the
first time the Strategy is accessed after a transaction is completed via
flush(). This might or might not begin a database transaction (this is
assumed to be figured out by the Strategy implementation). The flush()
method should commit the current work; release() should roll back any
uncommitted work and free all persistence resources.
We agreed that the PersistentObject is probably not the direction we
want to go, but we will need to look at it in detail. The equals method
in PersistentObject is suspect but we don't want to get rid of it
without looking at it a bit more. Methods in Hibernate Strategy also
take Assoc and HierarchicalPersistentObject in addition to
PersistentObject as arguments, and these need to be investigated as
well. These are the types of Bookmark, Category, and Folder (these are
complex aggregate objects that need special treatment for lifecycle
operations).
This item affects Roller in general and is something that should be
looked at in the relatively near future. A couple basic thoughts came
out of this ...
1. pojos shouldn't have to explicitly identify that they are persistent,
that should happen transparently. so eventually we would like to
eliminate the PersistentObject class.
2. the way persistent hierarchical objects work is complex and
confusing. it would be nice to reevaluate this code and see if it can
be simplified and improved.
The DatamapperQuery interface needs to be split into two parts, because
delete only has a small number of methods and it's required to know up
front if a query is going to be used for delete or query. We decided
that we would try to avoid using Update queries (Craig thinks Update
queries are ill-informed and should be avoided). Craig agreed to update
the DatamapperQuery interface and add a new DatamapperRemoveQuery
interface, along with a new newRemoveQuery method on
DatamapperPersistenceStrategy as a factory.
We think that the business objects generally can assume that all
operations use the same thread and the operations can therefore use a
thread-associated DatamapperPersistenceStrategy instance. Allen agreed
to look at some of the more complex operations involving tiles and
verify that the thread association is a good assumption.
I looked into this last week and found that this is indeed the case.
Any request coming into the appserver will remain on the same through
throughout its lifecycle.
-- Allen
Initialization of the environment uses a singleton pattern for
RollerImpl as well as all the XXXManager classes. All of the business
methods of XXXManager are stateless and therefore need to delegate to a
singleton Strategy. RollerImpl itself implemented a singleton pattern,
even though the caller, RollerFactory, itself implements the singleton
pattern. We changed the DatamapperRollerImpl to simple create an
instance each time the instantiate method was called, simplifying the
logic and eliminating the duplicate static instance.
The Strategy instance is also a singleton which allows the XXXManagers
to simply invoke the method, which is responsible for delegating to the
thread-associated implementation object (e.g. JDO PersistenceManager,
JPA EntityManager, or Hibernate Session).
For the most part, the XXXManager classes are responsible for a single
domain object class. Exceptions to this pattern are a few classes where
there is no clear separation, such as Bookmark which needs to manage the
set of classes associated with Bookmarks.
Where an XXXManager class needs to perform work that involves more than
one domain class, it should delegate to another XXXManager to do the
work. The pattern is to get the other XXXManager from the Roller
singleton and delegate. Things like iterating a collection of instances
acquired from another XXXManager should be looked at; it might be better
to delegate to a method in the other XXXManager that does the iteration
as well. Specific example is in PingTargetManagerImpl:
// Remove the website's auto ping configurations
AutoPingManager autoPingMgr =
RollerFactory.getRoller().getAutopingManager();
List autopings = autoPingMgr.getAutoPingsByTarget(ping);
Iterator it = autopings.iterator();
while(it.hasNext()) {
this.strategy.remove((AutoPingData) it.next());
}
We agreed that this might be better implemented as:
// Remove the website's auto ping configurations
AutoPingManager autoPingMgr =
RollerFactory.getRoller().getAutopingManager();
List autopings = autoPingMgr.removeAutoPingsByTarget(ping);
We agreed to meet again, same time, same place, on September 13.
Craig Russell
[EMAIL PROTECTED] http://db.apache.org/jdo