0
votes

When I try to run the following line

List<MessageEntity> list = 
                   ObjectifyService.ofy()
                       .load()
                       .type(MessageEntity.class)
                       .ancestor(Key.create(groupKey))
                       .order("dateSent")
                       .list();

I get the following error message:

"com.google.appengine.api.datastore.DatastoreNeedIndexException: no matching index found. recommended index is:\n- kind: MessageEntity\n ancestor: yes\n properties:\n - name: dateSent\n\nThe suggested index for this query is:\n \n \n \n\n"

If I remove the .order("dateSent") line it works fine and brings me all the coresponding entities in the datastore.

any idea what I could be doing wrong?

here's is my Entity Class

@Entity
public class MessageEntity implements EntityRoot {


@Parent
private Ref<GroupEntity> groupEntityRef;
@Id
private Long id;


private String message;
private String attachmentUrl;
private Ref<TenantUserEntity> sender;

@Index
private Long dateSent;

public MessageEntity(Ref<GroupEntity> groupEntityRef, String message, String attachmentUrl,
                     Ref<TenantUserEntity> sender, Long dateSent) {
    this.groupEntityRef = groupEntityRef;
    this.message = message;
    this.attachmentUrl = attachmentUrl;
    this.sender = sender;
    this.dateSent = dateSent;
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}

public String getAttachmentUrl() {
    return attachmentUrl;
}

public void setAttachmentUrl(String attachmentUrl) {
    this.attachmentUrl = attachmentUrl;
}

public Ref<TenantUserEntity> getSender() {
    return sender;
}

public void setSender(Ref<TenantUserEntity> sender) {
    this.sender = sender;
}

public Long getDateSent() {
    return dateSent;
}

public void setDateSent(Long dateSent) {
    this.dateSent = dateSent;
}

public Ref<GroupEntity> getGroupEntityRef() {
    return groupEntityRef;
}

@EmptyConstructor
public MessageEntity() {
}


@Override
public Key<? extends EntityRoot> getKey() {
    return Key.create(groupEntityRef.getKey(), MessageEntity.class, id);
}

}

P.S. I added the @Index annotation before creating the entities, while searching for this error I saw this as a common bug.

1

1 Answers

2
votes

The error message indicates a missing composite index.

@Index is used to annotate single-property indexes only, composite indexes still need to defined in datastore-indexes.xml, see Creating a Composite Index for AppEngine in Android-Studio-based project

What I suspect to be happening is that the ancestor query itself already uses an index (for the ancestor), so even if you're adding a single property in your query - .order("dateSent") - it is no longer a single index query and requires a composite index. That's why it works fine without the sorting. And it would work fine with sorting but if it wouldn't be an ancestor query.

Based on the content suggested in the error message you'd need this index in your datastore-indexes.xml:

    <datastore-index kind=\"MessageEntity\" ancestor=\"true\" source=\"manual\">
        <property name=\"dateSent\" direction=\"asc\"/>
    </datastore-index>

It could arguably be seen as an objectify bug, or at least its inability to properly format and display the suggested composite index.