Well, this is one of the major (maybe THE) drawback in appengine...apps architecture must be designed for the platform much more than with other kind of solutions.
Thinking a bit more about the original problem, there's a simple solution for all: you can simply put your Domain Key in each element, and mark it as a parent for the element as stated in http://code.google.com/intl/it/appengine/docs/java/datastore/transactions.html class Element....{ @Persistent @Extension(vendorName="datanucleus", key="gae.parent-pk", value="true") private Key domainKey; } This way all elements are in the same group of a domain, and transaction should work as long as you don't manipulate elements from multiple domains in a single transaction. Sorry for not stating it on first place, but I forgot abuot it.... On 26 Lug, 13:28, Bill <bill.milli...@gmail.com> wrote: > Hi Lorenzo, > > Certainly, this would work from a technical perspective. However, it > is absolutely not right for the problem. For a variety of reasons, > Domain and Element need to have a completely unowned relationship. > I'll explain some of my high-level situation: > > The Domain will be administered by a DomainAdministrator. This will > be either me, or someone personally known to me. For security > reasons, the DomainAdministrator has *no access* to the Elements that > "belong" to the Domain. The DomainAdministrator will also assign > authenticated users to what we can, for now, call the > ElementAdministrator role. > > An ElementAdministrator has access to administer Elements within the > context of assigned Domains. There may be thousands of Elements > within a single Domain. At no time should all the Elements within a > Domain ever be selected in a single operation. There would be no > point! Also, the security model I've designed will fragment Elements > further such that a User who is a member of the Domain will have > access to only some of the Elements in that Domain. > > In fact, one of the primary reasons I'm building the Element the way I > am is that Elements will be part of the fine-grained security model > itself. If a particular piece of data is selected in the system, I > need to check the user's profile's security elements against the > security elements baked into the data. This would necessitate a > datastore check, possibly in the middle of a transaction. > > If I have to manually twig the transaction on or off because of entity > groups, I'm defeating years of conventional wisdom on "separation of > concerns". I've designed my architecture the way I always have -- I > want to be able to bring on junior developers who don't have to make > decisions on low-level things like transactions and security. To > separate this concern, I'm using the extremely nice @Transactional > annotation within spring. If any service that inherits from my base > entity service interface is called on its "update()" method, for > instance, I want the whole thing to be transactional. It deeply pains > me that I could easily build this kind of a separated-concern solution > ten years ago with clunky hand-built libraries for a Weblogic > production environment, but I can't do it in 2010 with Google App > Engine. > > The fundamental problem with the concept of the entity group as a > restriction on transactional operations is that it mandates a > hierarchy on all operations. To be part of the entity group and > thence any operation in the transaction, it says, there must be a hard- > and-fast "owned" relationship between the entities. This looks very > nice on paper, but the problem is that if you're modelling the real > world, real world entities do not have nice hierarchical > relationships. For a very nice explanation of why this is a very > serious problem in solution design, see Christopher Alexander's > classic "A City Is Not A Tree" (it's available online for free). > > I've hacked around this for now, with a ten pound sledge hammer and a > rusty hacksaw. Using spring interceptors, I've built in an "extra- > transactional check" layer around my services, outside the aegis of > the transactional advisor. This is highly unsatisfactory because now > my developers are going to have to keep track of what is, and what > isn't part of the transaction. The concern is no longer neatly > separated. This is de-evolution. > > I absolutely love what leap forward Google App Engine represents in > terms of building applications. OTOH, the restrictions of entity > groups on transaction is a very real obstacle to building "serious" > business applications! > > Thanks, > > - Bill > > On Jul 26, 3:22 am, "l.denardo" <lorenzo.dena...@gmail.com> wrote: > > > As far as I know there are two possible solutions: > > > *Review the architecture inserting Elements as a list property of your > > domain, something like > > > @PersistenceCapable > > class Domain{ > > private ArrayList<Element> elements; > > > } > > > This works correctly and you get the benefit to have a cascasing > > delete on elements when you delete the Domain they're part of. > > This does not seem to have significant drawbacks, as documentation > > says somewhere Elements are fetched from datastore only if you access > > the list, and not if you just read the Domain without actually going > > thru the list. > > Elements are also queriable without reading the actual Domain they're > > in. > > The only thing this architecture seems to impede is finding the domain > > an element belongs to, given the element, without having complex > > iterations. > > > * Check if domain exists outside the transaction. > > If your domains are not deleted during an Element insert this should > > work. > > > I've gone the first path for my application and benefits in terms of > > code complexity and maintenance have been worth the effort, anyway it > > depends on your business logic if that can be right. > > > Regards > > Lorenzo > > > On Jul 24, 4:04 pm, Bill <bill.milli...@gmail.com> wrote: > > > > Hello, > > > > I'm quite frustrated with entity groups. They seem to make the > > > concept of a transaction largely pointless. > > > > The specific problem I face at this moment is this. Since the > > > datastore has no concept of foreign key constraints, I need to do > > > bounds checking. Here's the case: > > > > There exists a Domain type, and an Element type. An Element requires > > > a reference to a pre-existing Domain in order to function, per my > > > business rules. Domains exist independently of Elements, and are > > > administered separately. I would characterize their relationship as > > > "Element has a reference to a required Domain's primary key" rather > > > than "Element is a child of Domain". > > > > When creating an Element, I need to check that the reference to the > > > assigned Domain is not bogus. I do this in my service layer, which is > > > also where I want to determine transactionality. > > > > The algorithm goes like this: > > > > * start transaction. Per my current architecture I cannot start this > > > transaction any later without creating an entirely new non- > > > transactional business delegate layer that feels like absolute > > > overkill. > > > * retrieve Domain by key. If no such Domain is found, throw an error > > > * insert Element > > > * commit > > > > Unfortunately, this causes the dreaded "can't operate on multiple > > > entity groups in a single transaction" exception. I'm absolutely > > > hornswaggled by this, since I'm not "operating" on the Domain. I just > > > want to check that it exists! If this were a destructive change I > > > were making, I'd kind of -- barely -- see the argument here, but why > > > on earth is this a problem? Am I missing something? -- You received this message because you are subscribed to the Google Groups "Google App Engine for Java" group. To post to this group, send email to google-appengine-j...@googlegroups.com. To unsubscribe from this group, send email to google-appengine-java+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-appengine-java?hl=en.