1
votes

I'm posting the hole jsf method but the important row it's only: Food food = ofy().load().type(Food.class).id(lng).now();

public StreamedContent getImage() {
        if (getFacesContext().getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
            return new DefaultStreamedContent(); // So, we're rendering the HTML. Return a stub StreamedContent so that it will generate right URL.
        }
        String foodId = (String) getRequest().getParameter("foodId");
        Long lng = Long.parseLong(foodId);
        log.warning("GET image for Food ID: "+lng);
        Food food = ofy().load().type(Food.class).id(lng).now();
        return new DefaultStreamedContent(new ByteArrayInputStream(food.getImage()), "image/jpeg");
    }

Entity Food :

@Entity
public class Food implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id Long id;
    @Parent @Load Key<TableParent> owner;
    @Index String name;
    String description;
    byte[] image;
    @Load Ref<Category> category;

    public Food () {
    }

Yes. It has parent but I'm not posting it here because this parent shouldn't be used in simple query by ID. I'm sure that the id exists, and really don't see the reason to return always null. It's posible to be mater of consistency, but I'm doing this query over and over again on the same project. Works the same localy and deployed to google app engine - always returns null for object that existed for hours.

2

2 Answers

3
votes

The entity that has parent cannot be accessed without parent. I cannot access entity just by Id because there can be other entity with the same ID but other parent. So it's obligatory to use parent in such query:

Food food = ofy().cache(false).load().key(Key.create(Key.create(TableParent.class, parent.getId()), Food.class, lng)).now();

This gets the job done

2
votes

There is no way to query by id in GAE, unless you explicitly create a separate indexed field with the id value copied. But keep in mind that ids are only unique within a parent scope, so it probably doesn't do what you want.

Objectify's load-by-id is a load-by-key operation. Your example:

ofy().load().type(Food.class).id(lng).now();

Is just a shortcut for:

ofy().load().key(Key.create(Food.class, lng)).now();

Now you can see why you need to add the .parent() call too.