Google datastore objectify save issue with map - google-app-engine

remove(0) on a list having just one element in a map is making the map property disappear from an entity while saving to google datastore using objectify.
"map" is a property in the datastore entity.
Map<String, List<String>> map;
Saving after the following code causes the map property to disappear from datastore when the list corresponding to the key "dress" has just one element even if corresponding to other keys there are lists with any number of elements.
map.get("dress").remove(0)
Note: the issue does not happen when there is more than one element in the list.

Turns out there was a bug in the way map was being saved in Objectify version 5.1.8 all the way upto 5.1.12. We upgraded to 5.1.13 and this works now.

The default behavior of the Java SDK is as follows (from the docs):
Null properties are written as null to the data store
Empty collections are written as null to data store
A null is read as null from the data store
An empty collection is read as null.
You can change that so empty lists are preserved using
System.setProperty(DatastoreServiceConfig.DATASTORE_EMPTY_LIST_SUPPORT, Boolean.TRUE.toString())
Be sure to read the doc section listed above before turning that feature on; it lists several caveats to be aware of.

Related

Is Firestore a good database for storing many large objects in?

I have been using React/Leaflet to create a choropleth map that can color any country on the map. What I am trying to do is to develop a save/load function that saves the colored countries and later be able to import it from the database. When this object is saved and loaded, it can bring back the exact same countries that were colored. I have been using firebase/firestore but I haven't been getting any luck.
This is how my object of map data looks like
Is Firestore the right database to do it? Or should I approach another database? I need a database that can store multiple objects in the picture above.
If you can convert that file into a JSON of a size smaller than 1MB, which is the Firestore Document size limit, it is possible. In the case you are proposing I would have the following structure, from the information you shared but fell free to adapt it as you see fit:
Map Collection
field1
...
fieldN
CountriesOptions Subcollection
optionObject: {}
Where each object is a separate document in the CountriesOptions subcollection converted to JSON using JSON.stringify(obj).
For more information on how to structure your Firestore with subcollections you can check this link to the documentation.

RavenDB - How to backpopulate "old" documents after adding new property to POCO?

I'm just starting to learn about NoSQL/Document storage this morning. I am used to EntityFramework/SQLServer.
My questions is the following: If I have a bunch of "documents" stored and somewhere down the line I add a property to my class that is needed by my app, how do I back-populate the already existing records?
If you change the model after the fact then you have a few options.
If you have a default value for the additional field and can wait until the next time that entity is saved for the database then you can simply add the new property and set the value to the defaultv value in the constructor.
You can use a IDocumentConversionListener (http://ayende.com/blog/66563/ravendb-migrations-rolling-updates)
You can also use https://github.com/khalidabuhakmeh/RavenMigrations which I have never used but it seems like it would do what you want.

Save error: Initial term of field expression must be a concrete SObject: MAP<String,AcctId__c>

I'm trying to get over a limitation in Salesforce where Lead objects can't have related lists that convert with the Lead over to Opportunity, Contact and Account. I have set up 4 objects of type Lookup Relationship, and created a dummy record in each.
I want to use Custom Settings to store the id of each of these dummy records, so that when the Lead converts, any custom objects can also convert to objects with Master/Detail relationships on the respective standard objects.
My trigger on Lead(after update) tries to create a Map of the Custom Settings:
Map cs = AcctId__c.getAll();
AcctId__c is the Custom Setting api name. Compile time is giving me the above message.
Now, I copied this code directly from the Salesforce documentation. What am I forgetting?
I believe that you must include the actual map definition <String,AcctId__c> after the word Map.
Check out this page.
http://www.salesforce.com/us/developer/docs/apexcode/Content/langCon_apex_collections_maps.htm

Understanding ReferenceProperty backend behavior in GAE

I'm trying to understand a basic use case of working with GAE db.ReferenceProperties.
Example:
A Magazine db.Model entity has a db.ReferenceProperty(Publisher). I want to get a list of 10 Magazines to display in a table, that has a publisher column populated by model.publisher.name. Am I making 11 queries- one for the Magazine list result, and another one each everytime I reference the .publisher property?
The reference property isn't doing queries - it's doing datastore gets, which are faster - but you're correct that it does one per reference you resolve. You can batch them up using this pattern.

Change type of Datastore field to Text from String?

I can't seem to do this. The list that the app engine datastore viewer does not contain Text as an option. I had to change my fields because some of my values were too long for String, but now I can't retroactively fix my old entries.
To change the property type used by the old entities, you need to manually update each of them.
This can be easily and efficiently accomplished using the mapper API. This guide explains how to use this API.
You may also want to read this blog post by Nick Johnson.
You don't have to fix your old entries. The old ones should work as is, and the new ones just won't be indexed.
See
http://groups.google.com/group/google-appengine/browse_thread/thread/282dc825f9c46684 .

Resources