Re: [appengine-java] how to keep fields unique

2011-03-04 Thread Ed Murphy
I'm struggling with a bug that is closely related to this thread.  I think 
transactions all by themselves will not work here.  This is because the 
transactions are optimistic.  So, if the transaction looks like this (pseudo 
code)

pm.currentTransaction.begin();
Object preexistingEntity = pm.query(for secondary key);
if(null != preexistingEntity) throw SecondaryKeyException
pm.insert(new Entity(secondary key));
pm.currentTransaction.commit().


The issue (I think) is that because transactions are optimistic, it is still 
possible for a race condition.  Two separate processes can create a 
transaction and attempt to read the preexistingEntity.  If they are very 
close in time (like my case, 32 milliseconds), then they will both return 
null, since the entity does not yet exist.  So, neither process will throw 
the SecondaryKeyException.  The will both go on and create new entitities 
and insert them.  Each of these entities will have different primary keys 
because the database creates these, but the entity's secondary key (an email 
address in this case) is not enforced by the database, so there is no error 
on either commit.  Thus, I end up with two entities with a duplicate value 
for a field that I want to be unique.  

I my case, this happened when the user double-clicked an activation link; 
 The server received two requests within 50 milliseconds of each other and 
both transactions completed without error.  

I want to use a human readable, unique field for my users names.  I need the 
database generated unique id to create relationships with other entities 
that survive even if the human readable field is changed.  For instance, if 
a user changes their email address, I don't want to have to go around to all 
the possible related entities and fixup references to it.  So, I use the 
primary Key for this.  But I still want the email address to be unique in 
the database.

Anyone from Google know how to make this happen?  HELP


-- 
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-java@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.



Re: [appengine-java] how to keep fields unique

2011-03-04 Thread Ed Murphy
OK, here is something that looks promising; 

http://squeeville.com/2009/01/30/add-a-unique-constraint-to-google-app-engine/

This shows a solution in python, but the concept is applicable to Java. 
 Basically, for the unique field, you create another database entity and 
derive a primary Key based on the unique field.  Since the database ensures 
uniqueness of a primary key, this means that we can atomically create and 
check the existence of this entity.   So my pseudocode might look like;

pm.currentTransaction.begin();
Object preexistingKey = pm.insert(new SecondaryKeyEntity(secondary key));
pm.currentTransaction.commit();

//
// if we get here, then the previous transaction completed and
// no other process will be able to get to this section of the code
// using the same secondary key
//
pm.currentTransaction.begin();
pm.insert(new Entity(secondary key));
pm.currentTransaction.commit().

Of course, you need to do something similar when you change the secondary 
key (for instance, if someone wants to update their email address).  Again, 
just attempt to create an 'SecondaryKeyEntity' with the new email address. 
 If that successes, then you can change the email address in the primary 
entity.  Remember to delete the old SecondaryKeyEntity after!!

I'll work on this over the weekend and post some code if I figure it out.  

In the mean time, if anyone has already done this, please let us know. 
 Thanks.

-- 
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-java@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.



[appengine-java] Re: Task queue + datastore transaction + jdo: is it possible?

2011-01-11 Thread Ed Murphy
Yes, I do this with JDO.  Just add to you queue within the current
transaction, for instance;

PersistenceManager pm = PMF.get().getPersistenceManager();
try
{
//
// start transaction so we can atomically check the secondary key
//
pm.currentTransaction().begin();

//
// enqueue a task to process this ImportTask
//
//
String theUrl = /tasks; // whatever your url will be - this is is
your state;
Queue queue = QueueFactory.getDefaultQueue();
queue.add(

DatastoreServiceFactory.getDatastoreService().getCurrentTransaction(),
TaskOptions.Builder.url(theUrl));

//
// commit the transaction.
//
pm.currentTransaction().commit();   // we finished, so commit the
transaction.
}
catch(DataAccessException dae)
{
throw dae;  // let prior DataAccessException leave.
}
catch(Exception e)
{
throw new DataAccessException(e);   // wrap the exception in our
runtime exception.
}
finally
{
//
// if the transactions is still active, then there
// was an exception thrown.  So we rollback the transaction.
//
if(pm.currentTransaction().isActive())
{
pm.currentTransaction().rollback();
}

//
// we always close the PersistenceManager when done.
//
if(!pm.isClosed())
{
pm.close();
}
}


On Jan 11, 10:45 am, Fabrizio Accatino fht...@gmail.com wrote:
 Hello,

 documentation tells I can insert a task in queue during a datastore
 transaction.http://code.google.com/appengine/docs/java/taskqueue/overview.html#Ta...

 The example uses datastore low level api. Is there a way to do the same with
 JDO?

 Thank you

    Fabrizio

-- 
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.



[appengine-java] Re: SDK/Eclipse pains on Ubuntu

2010-10-26 Thread Ed Murphy
If you right-click your appengine project and choose properties from
the contextual menu (or just select the project and select properties
item in the Project menu on the menubar), you get the project
properties. Select the Google in the navbar on the left, then select
App Engine from the tree undeneath it. This shows the App Engine
control panel. It has radio buttons for choosing the version of the SDK
that you want to use. Next to the radio button Use default SDK there
is a configure SDKs link. Select that link, then choose an older SDK
as you default checking it.. Select OK to keep this selection and go
back to the App Engine control panel. Now make sure the Use default
SDK radio button is selected. Then select the OK button to close the
control panel. This _may_ cause the old jars to get copied. If it does,
you will see a progress window popup and then go away. Now re-open the
App Engine control panel. This time, choose the radio button Use
specific SDK and choose the most recent SDK in the pull down that is
just to the right. Select the OK button to close the control panel.
This time you _should_ see the progress window as the IDE copies the
latest SDK jars into your project.


Again, you are basically trying to get the plugin to detect that the
SDK version has changed. If it properly detects this, it will
automatically copy the jars into your project (and you will know this
is happening because it puts up the progress window).



Ed

-- 
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.



[appengine-java] Re: SDK/Eclipse pains on Ubuntu

2010-10-25 Thread Ed Murphy
I use Windows and I have the same problem when I upgrade and sometimes
when I create a new workspace. (tried to use Ubuntu, but can't get my
Adobe Flex plugin and Google plugin to both play nice). It seems the
the plugin update changes the SDK version, but does not copy the new
jars; it leaves the old ones or sometimes none. My workaround is to
basically to make the plugin re-copy the SDK jars into the project. I
do this by going into preferences and choosing Google. I then change
the SDK to a different version. Sometimes I need to also change the
default SDK, then choose a different one. The idea is to get the plugin
to realize that is must copy in the SDK jars. Usually I have to make to
copy the _old_ jars in, then I can change to the new SDK and have it
copy the new jars in. Works after that.


Also, your workspace may just be corrupt. So, if the above does not
work, create a new workspace and populate it from your source control,
then do the above if necessary. Hope this helps.

-- 
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.



[appengine-java] Re: How to use junit test in the newest SDK1.3.1

2010-03-02 Thread Ed Murphy
Thanks for starting this thread.  I have my Junit tests working,
including my datastore tests, but I have a question regarding project
setup.  I suppose this is more of an Eclipse question than anything
else, but perhaps you can help.  I've worked in NetBeans prior, and I
can setup a 'test' folder with my unit test source.  These classes are
excluded from the final war file. However, when I create a test folder
at the same level as my source folder:

Project
- src
- test

the only way I can make my tests work is to include test as a source
folder and add all the testing jars to my normal build path.  This
means my test classes end up in the deployment.

Can I have my tests in the same project as my source, or do I need to
have a separate project?

Thanks for you help.



On Feb 11, 10:43 am, Krishna Caldas krishnacal...@gmail.com wrote:
 Yes, I missed that method.
 Maybe add this little trick on tutorial for now!?

 Krishna

 2010/2/11 Max Ross (Google) maxr+appeng...@google.com:



  Great, glad to hear it!  I forgot to add a method to LocalServiceTestHelper
  to set a custom app id.  My mistake.  I'll make sure this gets added for the
  next release so you don't need to provide your ownEnvironment
  implementation.

  Max

  On Thu, Feb 11, 2010 at 10:30 AM, Krishna Caldas krishnacal...@gmail.com
  wrote:

  You're right!
  I refactored my code and forget to annotate the new setUp method with
  @Before.
  Sorry for taking your time! It works now.

  Thanks,
  Krishna

  2010/2/11 Max Ross (Google) maxr+appeng...@google.com:
   Your code looks fine.  Are you sure you're calling setUp() on the
   LocalServiceTestHelper?

   On Thu, Feb 11, 2010 at 10:11 AM, Krishna Caldas
   krishnacal...@gmail.com
   wrote:

   Ooops.. missed your question!
   It's just:
  @Override
  protectedEnvironmentnewEnvironment() {
  return new TestEnvironment();
  }

   Thanks,
   Krishna

   2010/2/11 Max Ross (Google) maxr+appeng...@google.com:
Subclassing LocalServiceTestHelper and overriding newEnvironment()
should
work fine.  What does your implementation of newEnvironment() look
like?

On Wed, Feb 10, 2010 at 7:35 PM, Krishna krishnacal...@gmail.com
wrote:

Ok!

But when I'm using transactions I'm getting:

java.lang.NullPointerException:NoAPIenvironmentisregisteredfor
thisthread.
   at

com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppId(Datas
 toreApiHelper.java:
67)
   at

com.google.appengine.api.datastore.DatastoreServiceImpl.beginTransaction(Da
 tastoreServiceImpl.java:
270)

I've tried to extend LocalServiceTestHelper and overwrite
newEnvironment()  with myEnvironment(who returns appId) but it
didn't work...

What's wrong?

Thanks,
Krishna

On Feb 10, 10:25 pm, Ikai L (Google) ika...@google.com wrote:
 We've got a more simple interface for you now. Take a look:

http://code.google.com/appengine/docs/java/tools/localunittesting.html

 2010/2/10 时空之蕊 skzr@gmail.com

  I found the class
  com.google.appengine.tools.development.ApiProxyLocalImpl is not
  public,but before 1.3.1 it's public!
  In the JUnit document:

  import java.io.File;
  import com.google.appengine.tools.development.ApiProxyLocalImpl;
  import com.google.apphosting.api.ApiProxy;

  ApiProxy.setDelegate(new ApiProxyLocalImpl(new File(.)){});

  So I can't new a ApiProxyLocalImpl instance!
  Any body know how to use JUnit?
  Thanks :)

  --
  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.comgoogle-appengine-java%2B
  unsubscr...@googlegroups.com
  .
  For more options, visit this group at
 http://groups.google.com/group/google-appengine-java?hl=en.

 --
 Ikai Lan
 Developer Programs Engineer, Google App

 Enginehttp://googleappengine.blogspot.com|http://twitter.com/app_engine

--
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.

--
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 

[appengine-java] Re: why my app on GAE first access is so slow

2010-01-04 Thread Ed Murphy
There are some proposed new features for GAE to allow apps to keep
their byte-code 'warm', either on the application server, or as a pre-
initialized image on disk that can be loaded and not incur a full
initialization.  Check out this issue, contribute suggestions and
vote for it if you want to see a feature like this;

http://code.google.com/p/googleappengine/issues/detail?id=2456


On Nov 7 2009, 3:22 am, Prashant antsh...@gmail.com wrote:
 yes, your guess is right. if your app is inactive then app engine will
 remove your app servlets from memory and reloads from datastore (or wherever
 it is stored) when you access it first time.

--

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.