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.