For the last part of the email (property validation) I was just looking again at the JSR-349 specification, whose last version has just been approved and incorporated to Java 7.
Seems that the reference implementation (Hibernate Validator) is Apache licensed [1]. How should it be used within an Apache Isis domain implementation? [1] http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/ El 06/08/2013, a las 19:10, GESCONSULTOR - Óscar Bou <[email protected]> escribió: > Thanks for your responses, Dan and Jeroen. Nice to be in "such a responsive" > environment :-) > > >> Part of the reason is in keeping the responsibilities of the various >> implementations consistent with each other. The Wicket viewer and the RO >> viewer now both set up transactions before doing any work, in other words >> we are using "session/transaction in view" design. > > Ok. We've been working with Hibernate this way without problems. So it's a > design option. And clearly, as I was not sure about the Isis transaction > management implementation, I implemented the "session-per-operation > antipattern" [1]. > > As we must implement the "session in view" for our own "viewer" (custom > Java-Spring-Dojo UI), is there any "class" we can reuse or inherit from? Or > should we "copy-and-adapt" the IsisTransactionFilterForRestfulObjects for > example? > > This same problem will be experienced by all the other viewers planned > (Javascript, DHTMLX, etc.) and also for anybody planning to "integrate" Isis > in their current applications, so it would be good for those use cases to > provide and support a "generic" session filter (similar to Spring's > "OpenSessionInViewFilter", for example [2]), that is independent of the > implementation technology used by the viewer (only on a session). > >> I've been mulling on how we can implement easily implement this. I'm not >> sure that FrameworkSynchronizer is the right place, because that will be >> called multiple times throughout the xactn. Instead, in IsisTransaction >> itself we have several enlistXxx() methods, already called by the JDO >> objectstore/FrameworkSynchronizer, originally added for auditing and >> publishing purposes. >> >> So, it seems it would be relatively trivial to additionally spin through >> all enlisted objects, and fire the validation checks on them, just prior to >> commit. This would be a bit like a pre-commit trigger. >> >> Another benefit of this design is that we know that at this point JDO/DN >> will have locked these objects exclusively, so there is no chance of the >> objects being changed under our feet. >> >> I think this is what the ticket you've raised, ISIS-487, should now >> implement. > > I've seen those classes, and seems that it can be the correct way for this > use case (validating before persisting), but there's another point detailed > next that I don't have as clear. > >>> If we were on a CQRS architecture, all property changes would be >>> considered a command and the DDD domain invariants would be guaranteed >>> before and after executing a command. > > > I seems to me that with the previous solution Isis will work as expected when > executing an "action". > > But I have more doubts when changing "properties". We could consider a change > in the value of a property a "simple" kind of action, inside a "setter" > method. But on Isis we also have other logic "attached" to a property change > (such as the validateXXX, hideXXX, disableXXX, etc.). > > The first time we looked at Isis and read the "How to add business rules" > section [3], we thought that Isis generated a proxy with CGLIB and when the > "setter" was invoked from any point in the Domain layer code (an action's > code, a service programmatic method, etc), the Isis proxy firstly invoked the > hiddenXXX, disableXXX and validateXXX methods (as on a wrapped object), in > order to verify that the property change was "valid". > > > Basically, our expectations when working with code at the domain layer (such > as in the domain objects and services actions and programmatic methods, and > on BDD unit-integration tests) were that: > - property change validation was done by "intercepting/proxying" the setter > call (avoiding the use of any "modifyXXX" methods). > - domain object validation was done before committing to the database > (obviously, a user could always perform a custom validation by invoking the > proper container's method). > > The second one is the previously discussed one. But can we also expect the > first option - or something equivalent - ? > > If not implemented, the "logic" of the "domain layer code" would not respect > the validation rules defined with Isis, forcing the introduction of > modifyXXX, addToXXX, removeFromXXX, etc. methods (as in managed > relationships), and replacing the "normal" setter invocations with a custom > "modifyXXX" methods, for example, just with the purpose of preserving the > business rules. > If, by error, a user invokes directly the setter, the Isis "validation logic" > would not be executed, which could lead to invalid states (that could be > acceptable when loading the objects from the objectstore - as we will be > guaranteeing they will always be saved in a correct state) but will be > unacceptable for code in the domain layer where domain objects can interact > without knowing that a modifyXXX method has been introduced, in addition to a > setXXX. > > > > Thanks again, > > Oscar > > > [1] > http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/transactions.html > [2] > http://static.springsource.org/spring/docs/1.2.9/api/org/springframework/orm/hibernate3/support/OpenSessionInViewFilter.html > [3] http://isis.apache.org/applib-guide/how-tos/about.html > > > El 06/08/2013, a las 08:15, Dan Haywood <[email protected]> > escribió: > >> Oscar, >> >> You've convinced me... we should keep our entities consistent across the >> layers. More discussion inline below.... >> Dan >> >> >> On 5 August 2013 17:00, GESCONSULTOR - Óscar Bou >> <[email protected]>wrote: >> >>>> But I presume there was a reason that you put your call to >>>> AbstractXMSDomainObjectRepositoryAndFactory#.doFindByProp(...) in this >>>> closure. Can you tell me explain further for me? >>> >>> >>> The reason is that we are adapting our current viewer (user interface) to >>> Isis. There is common functionality to all screens (such as filtering, >>> searching, saving a domain object, refresh, etc.) that work with methods >>> defined on a base repository (AbstractXMSDomainObjectRepositoryAndFactory). >>> >>> As all Isis interaction is made inside those methods, we surrounded all >>> that logic within a Isis transaction, thinking that would allow as to avoid >>> custom web session filters, etc. >>> It was the "closest" place to the code interacting with Isis. Can you >>> explain a bit the advantages about why should it be done on a "higher >>> layer" - the web session - (perhaps if not done through a web session >>> filter it can introduce some "session management" problems (seeing >>> different object sets or different Isis sessions depending on the "session" >>> returned by Tomcat - in different states/update time - , etc.). >>> >>> >> Part of the reason is in keeping the responsibilities of the various >> implementations consistent with each other. The Wicket viewer and the RO >> viewer now both set up transactions before doing any work, in other words >> we are using "session/transaction in view" design. >> >> I only added the IsisTransactionFilterForRestfulObjects very recently; >> until then it was also relying on the lazy creation of transactions down in >> the PersistenceManager. But what it also means is that any queries for >> objects are done without a transaction in place (I guess that the JDO/DN >> and/or the RDBMS creates one implicitly). I could see in the future that >> we might want to allow the user to use isolation level 3 rather than level >> 1, ie guarantee that a transaction exists and is present. >> >> >> >> >>> >>>> At the moment we only ever apply such validation at the UI layer, >>> mediating >>>> between the viewer layer and the domain object model/layer. >>> >>> This was not our expectation. And I think this is not the expected >>> behavior in other "validation" frameworks. I'll further detail this. >>> >> >> You've convinced me... we should keep our entities consistent across the >> layers. I don't know that I really thought otherwise, was just aware that >> this was an area where the current implementation of Isis was less than >> ideal. >> >> [snip] >> >> >>> So, at least, I could expect: >>> - After any action execution, all domain objects are in compliance with >>> all defined invariants. >>> - During action execution, I could understand that objects are not >>> conformant with invariants. >>> - If a property is modified on a viewer, when the object changes are >>> saved/persisted (sent to Isis and, through it, to the database) all >>> invariants are in place. >>> >>> >> I've been mulling on how we can implement easily implement this. I'm not >> sure that FrameworkSynchronizer is the right place, because that will be >> called multiple times throughout the xactn. Instead, in IsisTransaction >> itself we have several enlistXxx() methods, already called by the JDO >> objectstore/FrameworkSynchronizer, originally added for auditing and >> publishing purposes. >> >> So, it seems it would be relatively trivial to additionally spin through >> all enlisted objects, and fire the validation checks on them, just prior to >> commit. This would be a bit like a pre-commit trigger. >> >> Another benefit of this design is that we know that at this point JDO/DN >> will have locked these objects exclusively, so there is no chance of the >> objects being changed under our feet. >> >> I think this is what the ticket you've raised, ISIS-487, should now >> implement. >> >> >> >> >>> If we were on a CQRS architecture, all property changes would be >>> considered a command and the DDD domain invariants would be guaranteed >>> before and after executing a command. And perhaps that would be the meaning >>> of an "Isis Transaction", differenciating it from a database transaction or >>> an "application layer transaction" (such as in SAP, where it's referred as >>> an operations requiring work in one or more than one views, as in a >>> wizard)). >>> >> >> I don't see an IsisTransaction as having a different scope to a database >> transaction; it's a single short-lived transaction in force for the >> duration of the invocation of an object action (or property edit). But >> what it can/does provide is this ability to find the enlisted objects and >> do useful things to/with them. >> >> Appreciate you spending the time to make these arguments; good stuff. >> >> Dan >
