Good thought, but unforunately Elements already have a parent key in
this manner.  Elements are hierarchical, so that an Element's parent
is another parent.

Can an entity have more than one parent?  I haven't tried that...

For more reference, here are all the fields that might be of interest
to this problem:

@PersistenceCapable ( identityType = IdentityType.APPLICATION )
@Version (
        strategy=VersionStrategy.VERSION_NUMBER,
        extensions = { @Extension ( vendorName = "datanucleus", key = "field-
name", value = "version" ) }
)
public class Element {

        @Persistent ( valueStrategy = IdGeneratorStrategy.IDENTITY )
        @PrimaryKey
        @Extension ( vendorName = "dataNucleus", key = "gae.encoded-pk",
value="true" )
        @Immutable
        private String key ;

        @Persistent
        @Extension ( vendorName = "datanucleus", key = "gae.parent-pk", value
= "true" )
        @Immutable
        private String parentKey ;

        private long version ;

        @Persistent
        @Immutable
        private String domain ;

        // etc., etc., etc.
}

On Jul 26, 8:14 am, "l.denardo" <[email protected]> wrote:
> 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/transact...
>
> 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 <[email protected]> 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" <[email protected]> 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 <[email protected]> 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 [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en.

Reply via email to