Hi,
  The issue is probably that fileService.getBlobKey (and other
methods) makes a datastore call (at least the Python version does).
Since transactions can only touch one entity group, you might get some
problems.  (I didn't read your code that closely, but perhaps that
will help you track it down.)

    
http://code.google.com/appengine/docs/java/datastore/transactions.html#What_Can_Be_Done_In_a_Transaction



Robert






On Mon, Aug 22, 2011 at 00:08, Jared Alexander
<[email protected]> wrote:
> I have a Java Google App Engine web application that allows user upload of
> images. Locally, it works great.  However, once I deploy it to "the cloud",
> and I upload an image, I get the following error:
> java.lang.IllegalArgumentException: can't operate on multiple entity groups
> in a single transaction.
> I use the blobstore to store the images (BlobStore
> reference: http://code.google.com/appengine/docs/java/blobstore/overview.html#Writing_Files_to_the_Blobstore).
>  My method is below:
>
>     @RequestMapping(value = "/ajax/uploadWelcomeImage", method =
> RequestMethod.POST)
> @ResponseBody
> public String uploadWelcomeImage(@RequestParam("id") long id,
> HttpServletRequest request) throws IOException, ServletException {
> byte[] bytes = IOUtils.toByteArray(request.getInputStream());
> Key parentKey = KeyFactory.createKey(ParentClass.class.getSimpleName(),
> id);
> String blobKey = imageService.saveImageToBlobStore(bytes);
> imageService.save(blobKey, parentKey);
> return "{success:true, id:\"" + blobKey + "\"}";
> }
>
> You'll notice that this method first calls
> "imageService.saveImageToBlobStore".  This is what actually saves the bytes
> of the image.  The method "imageService.save" takes the generated blobKey
> and wraps it in an ImageFile object, which is an object that contains a
> String blobKey.  My website references imageFile.blobKey to get the correct
> image to display.  The "saveImageToBlobStore" looks like this:
>
>     @Transactional
> public String saveImageToBlobStore(byte[] bytes) {
> // Get a file service
> FileService fileService = FileServiceFactory.getFileService();
> // Create a new Blob file with mime-type "text/plain"
> AppEngineFile file = null;
> try {
> file = fileService.createNewBlobFile("image/jpeg");
> } catch (IOException e) {
> e.printStackTrace();
> }
> // Open a channel to write to it
> boolean lock = true;
> FileWriteChannel writeChannel = null;
> try {
> writeChannel = fileService.openWriteChannel(file, lock);
> } catch (FileNotFoundException e) {
> e.printStackTrace();
> } catch (FinalizationException e) {
> e.printStackTrace();
> } catch (LockException e) {
> e.printStackTrace();
> } catch (IOException e) {
> e.printStackTrace();
> }
> // This time we write to the channel using standard Java
> try {
> writeChannel.write(ByteBuffer.wrap(bytes));
> } catch (IOException e) {
> e.printStackTrace();
> }
> // Now finalize
> try {
> writeChannel.closeFinally();
> } catch (IllegalStateException e) {
> e.printStackTrace();
> } catch (IOException e) {
> e.printStackTrace();
> }
> // Now read from the file using the Blobstore API
> BlobKey blobKey = fileService.getBlobKey(file);
> while (blobKey == null) { //this is hacky, but necessary as sometimes the
> blobkey isn't available right away
> try {
> Thread.sleep(2000);
> } catch (InterruptedException e) {
> e.printStackTrace();
> }
> blobKey = fileService.getBlobKey(file);
> }
> // return
> return blobKey.getKeyString();
> }
>
> My other save method looks like this:
>
>     public void save(String imageFileBlobKey, Key parentKey) {
> DatastoreService datastore = DatastoreServiceFactory
> .getDatastoreService();
> Entity imageFileEntity = new Entity("ImageFile", parentKey);
> imageFileEntity.setProperty("blobKey", imageFileBlobKey);
> datastore.put(imageFileEntity);
> }
>
> Like I said before, it works locally, but not deployed. The error is on the
> call to saveImageToBlobstore, specifically on the
> "fileservice.getBlobKey(file)". Commenting out this line eliminates the
> error, but I need this line to save the bytes of the image to the blob
> store.  Any ideas?  I am using GAE 1.5.2.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "Google App Engine" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/google-appengine/-/HQPIJdRNp7EJ.
> 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?hl=en.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Google App Engine" 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?hl=en.

Reply via email to