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.

Reply via email to