| 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). 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. 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. |
smime.p7s
Description: S/MIME cryptographic signature
