4

So, I have an unidirectional one-to-many relationship where I want to keep the children in an ordered list. Since they already have an "index" property, I tried to follow the advice on http://code.google.com/appengine/docs/java/datastore/jdo/relationships.html and use the "list-ordering" extension to use that index-property to determine the order of the children instead of using an auto-generated one.

Unfortunately, as soon as I add the annotation it stops returning children and only gives me an empty list.

I recreated the problem with this simple example:

@PersistenceCapable(detachable = "true")
@FetchGroup(name = "parent.children", members = {@Persistent(name = "children")})
public class Parent {
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;

    @Persistent
    @Order(extensions = @Extension(vendorName="datanucleus", key="list-ordering", value="index ASC"))
    private List<Child> children;

    // getters/setters
}

@PersistenceCapable(detachable = "true")
public class Child {
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;

    @Persistent
    private Integer index;

    // getters/setters
}

DAO:

public void save(T entity) {
    PersistenceManager pm = getPersistenceManager();
    Transaction tx = pm.currentTransaction();
    try {
        tx.begin();
        pm.makePersistent(entity);
        tx.commit();
    } finally {
        if(tx.isActive())
            tx.rollback();
        pm.close();
    }
}

public T get(Key key, String... fetchGroups) {
     PersistenceManager pm = getPersistenceManager();
     Transaction tx = pm.currentTransaction();
     addFetchGroups(pm, fetchGroups);
     try {
         tx.begin();
         pm.setDetachAllOnCommit(true);
         T entity = (T) pm.getObjectById(entityClass, key);
         tx.commit();
         return entity;
     } finally {
         if(tx.isActive())
             tx.rollback();
         pm.close();
     }
}

Test code:

Parent parent = new Parent();
Child child = new Child(); 
child.setIndex(10);
parent.getChildren().add(child);
mParentDao.save(parent);

Parent parent2 = mParentDao.get(parent.getKey(), "parent.children");

Is there anything in particular that I am doing wrong?

[EDIT] Here is the related log output:

Datastore: Putting entity of kind PARENT with key PARENT(no-id-yet)
Datastore: Putting entity of kind CHILD with key PARENT(3)/CHILD(no-id-yet)
Datastore: INDEX : 10
Datastore: Committed datastore transaction: 0
Datastore: Started new datastore transaction: 1
Datastore: Getting entity of kind PARENT with key PARENT(3)
Datastore.Retrieve: Preparing to query for all children of PARENT(3) of kind CHILD
Datastore.Retrieve: Added sort: index ASCENDING
Datastore.Retrieve: Query had 0 results.
Datastore: Committed datastore transaction: 1
Timo Ohr
  • 7,947
  • 2
  • 30
  • 20
  • Works for me. I'm using v2 of the GAE plugin. Use the log to debug it, since it tells you the puts and gets to the GAE datastore – DataNucleus Mar 19 '12 at 18:46
  • I added some of the log output. Seems fine, basically.. the entities are added correctly and do appear in the datastore, but for some reason when querying for children he receives 0 results. – Timo Ohr Apr 01 '12 at 17:00
  • I had a similar problem that puzzled me for some time. Ordered lists must be used with caution, specially if you CHANGE the ordering field before commit. Workaround: REMOVE the order tag, and implement a COMPARATOR on the list. – marcolopes Oct 21 '12 at 03:06

1 Answers1

0

Im using GAE plugin 1.7.0 with JDO and my scenario is exactly the same. I have a list of items and i need to maintain their order as well.

Now i used the app for a long period of time without doing the above changes (without implementing the feature).

Today i implemented order feature using the article and the data isn't being retrieved! the data is present in database but are not fetched during parent object load. Even though the list is marked with:

@Persistent(defaultFetchGroup = "true")

@Element(dependent = "true")

Srinivas
  • 432
  • 5
  • 22