0

I'm working with Objectify to access DataStore in a Google App Engine application.

I have 2 Entities:

@Entity
public class Client {
    @Id String id;
}

@Entity
public class Queue {
    @Index @Id String name;     
    @Load LinkedHashMap<String,Ref<Client>> clientsInQueue;
}

In a transaction, i do something like this:

Client newClient = new Client(...);
ofy().save().entity(newClient);

Queue selectedQueue = ofy().load().type(Queue.class).id(queueName).now();
selectedQueue.getClientsInQueue().put(newClient.getId(), Ref.create(newClient));

But when i try to print all the elements in the LinkedHashMap, i noticed the elements is in the exactly reverse order.

For example if i add 2 Clients in the LinkedHashMap and save it, like this:

Queue selectedQueue = new LinkedHashMap<String,Ref<Client>>();
String id1 = "id1";
Client c1 = new Client(id1);
ofy().save().entity(c1);    
String id2 = "id2"
Client c2 = new Client(id2);
ofy().save().entity(c2);    

selectedQueue.getClientsInQueue().put(c1.getId(), Ref.create(c1)); 
selectedQueue.getClientsInQueue().put(c2.getId(), Ref.create(c2));
ofy().save().entity(selectedQueue); 

Set<String> keys = selectedQueue.getClientsInQueue().keySet();

for(String key : keys){
    Client c= selectedQueue.getClientsInQueue().get(key).get();
    log.info("id: "+c.getId());
}

The result is:

id: id2

id: id1

Why i obtain this behavior ? I know that LinkedHashMap has to maintain the order of the keys! Is there any problem to use LinkedHashMap with GAE DataStore?

Thanks in advance. Cheers, Alessandro.

mancioshell
  • 27
  • 2
  • 10
  • [LinkedHashMap](http://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashMap.html) Hash table and linked list implementation of the Map interface, with predictable iteration order. This implementation differs from HashMap in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order). – mancioshell Jan 28 '15 at 10:00

1 Answers1

2

Fields of type Map<String, ?> are stored in the low level api as type EmbeddedEntity, the only map-like structure available as a property. This EmbeddedEntity is implemented as a non-linked HashMap. Consequently, there is no way for Objectify to preserve order.

I'll make a note of this in Objectify's documentation. If you would like this behavior to change, open up an issue in GAE's issue tracker requesting "Entity and EmbeddedEntity should use a LinkedHashMap to preserve order".

stickfigure
  • 13,458
  • 5
  • 34
  • 50