@Entity
public class Category {
    @Id
    private Long id;
    private String name;
    private String description;
    @Load
    private List<Ref<Subcategory>> subcategories = new ArrayList<Ref<Subcategory>>();
    @Load
    private Ref<Image> image;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public List<Subcategory> getSubcategories() {
        List<Subcategory> scs = new ArrayList<Subcategory>();
        for (Ref<Subcategory> sc : this.subcategories) {
            scs.add(sc.get());
        }
        return scs;
    }
    public void setSubcategory(Subcategory subcategory) {
        this.subcategories.add(Ref.create(subcategory));
    }
    public Image getImage() {
        if(image != null) {
            return image.get();
        }
        return null;
    }
    public void setImage(Image image) {
        this.image = Ref.create(image);
    }
}
@Entity
public class Subcategory {
    @Id
    private Long id;
    private String name;
    private String description;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
public class CategoryDTO {
    private Long id;
    @NotNull
    private String name;
    private String description;
    private List<Subcategory> subcategories = new ArrayList<Subcategory>();
    private Long imageId;
    public CategoryDTO() {
    }
    public CategoryDTO(Category category) {
        this.id = category.getId();
        this.name = category.getName();
        this.description = category.getDescription();
        this.subcategories = category.getSubcategories();
        if (category.getImage() != null) {
            this.imageId = category.getImage().getId();
        }
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public List<Subcategory> getSubcategories() {
        return subcategories;
    }
    public void setSubcategories(List<Subcategory> subcategories) {
        this.subcategories = subcategories;
    }
    public Long getImageId() {
        return imageId;
    }
    public void setImageId(Long imageId) {
        this.imageId = imageId;
    }
}
CategoryDAO
public class CategoryDAO {
    private static final Logger log = Logger.getLogger(CategoryService.class.getName());
    public static QueryResultIterator<Category> getCategories() {
        QueryResultIterator<Category> categories = ofy().load().type(Category.class).iterator();
        return categories;
    }
}
public class SubcategoryDAO {
    public static Subcategory createSubcategory(Long categoryId, Subcategory data) {
        // save sub category
        Subcategory subcategory = new Subcategory();
        if (data.getName() != null) {
            subcategory.setName(data.getName());
        }
        if (data.getDescription() != null) {
            subcategory.setDescription(data.getDescription());
        }
        ofy().save().entity(subcategory).now();
        Category category =
            ofy().load().type(Category.class).id(categoryId).get();
        category.setSubcategory(subcategory);
        ofy().save().entity(category).now();
        return subcategory;
    }
}
CategoryService
@Path("/categories")
public class CategoryService {
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public String getCategories() {
        try {
            List<CategoryDTO> categories = new ArrayList<CategoryDTO>();
            QueryResultIterator<Category> cats = CategoryDAO.getCategories();
            while (cats.hasNext()) {
                categories.add(new CategoryDTO(cats.next()));
            }
            Map<String, List<CategoryDTO>> map = new HashMap<String, List<CategoryDTO>>();
            map.put("categories", categories);
            return Helper.prepareResponse(map);
        } catch (Exception e) {
            LogService.getLogger().severe(e.getMessage());
            throw new WebApplicationException(500);
        }
    }
}
Problem:-
When i hit getCategories service, it is showing unexpected behaviour.Instead of showing all the subcategories, it is showing random no of different subcategories every time.
For example say, first i save a category "c" then i save subcategories "sa", "sb" and "sc"
On hitting getCategry service,
Expected Behaviour -
{
    "status": 200,
    "categories" : [{ 
        "name":a, 
        "subcategories": [
            {
                "name":"sa"
            }, 
            {
                "name":"sb"
            }, 
            {
                "name":"sc"
            } 
        ]
    }]
}
Outputs i get is something like this -
{
    "status": 200,
    "categories" : [{ 
        "name":a, 
        "subcategories": [
            {
                "name":"sa"
            }, 
            {
                "name":"sc"
            } 
        ]
    }]
}
or
{
    "status": 200,
    "categories" : [{ 
        "name":a, 
        "subcategories": [{
            "name":"sb"
        }]
    }]
}
				
                        
Welcome to the wonderful world of eventual consistency. When I encountered something like this, using ObjectifyService.begin() instead of ObjectifyService.ofy() resolved it. Unlike ofy(), begin() gets you fresh data every time.