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.
