@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.