Objectify Java Reference - java

#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"
}]
}]
}

To summarize this question, you're performing a query (give list of all categories) and getting back inconsistent results.
This is the system working as advertised. Read this: https://cloud.google.com/appengine/docs/java/datastore/structuring_for_strong_consistency
Eventual consistency is something that you learn to live with and work around when you need it. There is no way to force a query to be strongly consistent without changing the structure of your data - say, put it under a single entity group - but that has repercussions as well. There is no free lunch if you want a globally replicated, infinitely-scalable database.
In addition to eventual consistency, the datastore has no defined ordering behavior if you do not specify a sort order in your query. So that might add to your confusion.

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.

Related

JSON parse error: Cannot deserialize instance of.. out of START_ARRAY token

I know there are a few questions on stackoverflow regarding this problem. But I have have been spending hours trying to resolve this error without any success.
I am using the mysql database to store the values.
I keep on getting the error message from the
com.example.springboot.Recipe file.
This is springboot recipe file
package com.example.springboot;
import com.example.springboot.Recipe;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
#Entity // This tells Hibernate to make a table out of this class
public class Recipe {
public Recipe(){
}
public Recipe(Integer id, String name, String description, String type, Integer preptime, Integer cooktime, String content, Integer difficulty){
this.id = id;
this.name = name;
this.description = description;
this.type = type;
this.preptime = preptimee;
this.cooktime = cooktime;
this.content = content;
this.difficulty = difficulty;
}
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private String description;
private String type;
private Integer preptime;
private Integer cooktime;
#Column(columnDefinition = "TEXT")
private String content;
private Integer difficulty;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return name;
}
public void setTitle(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Integer getDifficulty() {
return difficulty;
}
public void setDifficulty(Integer difficulty) {
this.difficulty = difficulty;
}
public Integer getCookingtime() {
return cooktime;
}
public void setCookingtimeime(Integer cooktime) {
this.cooktime = cooktime;
}
public Integer getPreparationtime() {
return preptime;
}
public void setPreparationtime(Integer preptime) {
this.preptime = preptime;
}
}
Main Controller:
#PutMapping("/recipes/edit/{id}")
void updateRecipe2(#PathVariable int id, #RequestBody Recipe recipe ) {
Recipe recipe_ = recipeRepository.findById(id).get();
recipe_.setTitle(recipe.getTitle());
System.out.println("sss " + recipe.getname());
System.out.println("change");
recipeRepository.save(recipe_);
}
service.ts:
updateRecipe2 (id: number, recipe: any): Observable<any > {
const url = `${this.usersUrl}/edit/${id}`;
return this.http.put(url ,recipe);
}
where the updateRecipe2 gets called:
save(): void {
const id = +this.route.snapshot.paramMap.get('name');
this.recipeService.updateRecipe2(id, this.recipes)
.subscribe(() => this.gotoUserList());
}
as soon as the user clicks save this functions saves the changes made.
I hope the code snippets that I provided are enough to help solve the problem.
Thank you in advance.
I am building a rest api with spring boot and I am using angularjs as it's frontend. I am pretty new to web-development.
You are sending a list of recipes to an api endpoint that expects a single recipe object.
Your options are:
Send only one recipe object at a time, for example:
this.recipeService.updateRecipe2(id, this.recipes[0])
OR: create a new API endpoint to accept a list of recipes, to edit them in "batch"
#PutMapping("/recipes/edit")
void updateRecipes(#RequestBody List<Recipe> recipe ) {
my Example:
Use:
#PostMapping
Code:
public void setTransacciones(List<Transacciones> transacciones) {
this.transacciones = transacciones;
}
CodeBean:
public class Transacciones {
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
private String text;
}
Post(raw):
{
"transacciones" : [ {"text" : "1"}, {"text" : "2"} ]
}
Result:
{
"transacciones": [
{
"transaccionId": 2,
"text": "1"
},
{
"transaccionId": 3,
"text": "2"
}
]
}
BINGO!!

How to read JSON array values in Spring controller

I would like to iterate Products and get the list of name,code and price and set in my Model class. Any help would be really appreciated - how can I iterate this. When I use obj.get("Products") - it just printing as string - got stuck to iterate.
{
"id": "skd3303ll333",
"Products": [{
"name": "apple",
"code": "iphone-393",
"price": "1939"
},
{
"name": "ipad",
"code": "ipad-3939",
"price": "900"
}
]
}
#PostMapping(path="/create", consumes=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> create(#RequestBody Map<String, Object> obj ) {
System.out.println("Products :" + obj.get("Products"));
}
There are two ways to do this,
1) By type casting (personally i will not prefer this)
List<Map<Object,Object>> productslist = (List<Map<Object, Object>>) obj.get("products");
for(Map entry: productslist) {
for(Object s: entry.keySet()) {
System.out.println(s.toString());
System.out.println(entry.get(s).toString());
}
}
2) Mapping directly to Model class, for this approach you need Jackson library in buildpath
#JsonIgnoreProperties(unknown =true)
public class Customer {
#JsonProperty("id")
private String id;
#JsonProperty("products")
private List<Products> products;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Products> getProducts() {
return products;
}
public void setProducts(List<Products> products) {
this.products = products;
}
}
#JsonIgnoreProperties(unknown =true)
class Products{
#JsonProperty("name")
private String name;
#JsonProperty("code")
private String code;
#JsonProperty("price")
private String price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
Controller
public ResponseEntity<Object> create(#RequestBody Customer obj ) {
You need POJO structure with two classes:
public class Product {
private String name;
private String code;
private int price;
}
public class ProductsGroup {
private long id;
private List<Product> products;
// getters/setters
}
And change your method signature to:
#PostMapping(path="/create", consumes=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ProductsGroup> create(#RequestBody ProductsGroup productGroup)
{
System.out.println("Products :" + productGroup.getProducts());
}
You are trying to process the json using a Map<String, Object> obj, which could be possible in some way, but mostly what you want to do is define a single or multiple POJO classes. These represent the json.
public class IdWrapper {
private String id;
#JsonProperty("Products")
private List<Product> products;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Product> getProducts() {
return products;
}
}
public class Product {
private String name;
private String code;
private String price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
And in you controller like this:
#RestController
#RequestMapping("test")
public class DemoController {
#PostMapping()
public void test(#RequestBody IdWrapper productsWrapper) {
System.out.println();
}
}

POST a list of items spring boot

#RestController
public class TopicController {
#Autowired
private TopicService topicService;
#RequestMapping(value="/topics", method= RequestMethod.GET)
public List<Topic> getAllTopics(){
return topicService.getAllTopics();
}
#RequestMapping(value="/topics/{id}", method= RequestMethod.GET)
public Topic getTopic(#PathVariable String id){
return topicService.getTopic(id);
}
#RequestMapping(value="/topics", method= RequestMethod.POST)
public void addTopic(#RequestBody Topic topic){
topicService.addTopic(topic);
}
#RequestMapping(value="/topics/{id}", method= RequestMethod.PUT)
public void updateTopic(#RequestBody Topic topic, #PathVariable String id){
topicService.updateTopic(id, topic);
}
#RequestMapping(value="/topics/{id}", method= RequestMethod.DELETE)
public void deleteTopic(#PathVariable String id){
topicService.deleteTopic(id);
}
}
Controller class
#Service
public class TopicService {
#Autowired
private TopicRepository topicRepo;
public List<Topic> getAllTopics(){
return (List<Topic>)topicRepo.findAll();
}
public Topic getTopic(String id){
return topicRepo.findOne(id);
}
public void addTopic(Topic topic){
//topics.add(topic);
topicRepo.save(topic);
}
public void updateTopic(String id, Topic topic) {
topicRepo.save(topic);
}
public void deleteTopic(String id) {
//topics.removeIf(t -> t.getId().equals(id));
//topics.removeIf((Topic t) -> t.getId().equals(id));
topicRepo.delete(id);
}
}
Service Class
#Repository
public interface TopicRepository extends CrudRepository<Topic, String>{
//List<Course> findByTopic_Id(String topicid);
}
Repository Class
#Entity
public class Topic {
#Id
#Column(name="TOPIC_ID")
private String id;
#Column(name="NAME")
private String name;
#Column(name="DESCRIPTION")
private String description;
#OneToMany(mappedBy="topic", fetch = FetchType.EAGER)
#JsonManagedReference
private List<Course> course = new ArrayList<Course>();
//no - argument constructor. Needed for hibernate
public Topic(){};
public Topic(String id, String name, String description, List<Course> course){
super();
this.id = id;
this.name = name;
this.description = description;
this.course = course;
}
public Topic(String id, String name, String description){
super();
this.id = id;
this.name = name;
this.description = description;
}
public String getId() {
return id;
}
public void setId(String 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<Course> getCourse() {
return course;
}
public void setCourse(List<Course> course) {
this.course = course;
}
}
Topic Class
#Entity
public class Course{
#Id
#Column(name="COURSE_ID")
private String id;
private String name;
private String description;
//There could be many courses related to 1 topic
#ManyToOne
#JoinColumn(name = "TOPIC_ID")
#JsonBackReference
private Topic topic;
public Course(){};
public Course(String id, String name, String description){
super();
this.id = id;
this.name = name;
this.description = description;
}
public Topic getTopic() {
return topic;
}
public void setTopic(Topic topic) {
this.topic = topic;
}
public String getId() {
return id;
}
public void setId(String 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;
}
}
Course Class
I am trying to use Postman to post a Topic class which contains many Courses into my sql database.
In Postman, I did the POST using JSON like this
{
"id": "700",
"name": "How to countt",
"description": "Counting numbersssss",
"course": [
{
"id": "1",
"name": "php",
"description": "gooddddyyyy stuff"
},
{
"id": "2",
"name": "phpp",
"description": "gooddddyyyy stuffp"
}
]
}
However, when i do the corresponding get all topics, my response was
{
"id": "700",
"name": "How to countt",
"description": "Counting numbersssss",
"course": []
}
It is not picking up the courses that i posted. One Topic can have many Courses. How do i fix this? Thank you
You never set the owning side of the bidirectional association: Course.topic.
And there is no cascade set on Topic.courses.
So, not only saving a topic won't save its courses, but even if it did, the courses would not belong to their topic.

json and wrapper for gson

I am trying to get some the array of actors from Jira. The code for the wrapper is used in a Gson.fromJson call. I had used something similar with a json string that did not have an array in it that had the information I needed and it worked fine, so the issue seems to do with the array, but I am not 100% sure:
import com.google.gson.annotations.SerializedName;
public class JiraRoleJsonWrapper {
#SerializedName("self")
private String self;
#SerializedName("name")
private String name;
#SerializedName("id")
private int id;
#SerializedName("description")
private String description;
#SerializedName("actors")
private JiraActors[] actors;
public JiraActors[] getActors() {
return actors;
}
public void setActors(JiraActors[] actors) {
this.actors = actors;
}
public String getSelf() {
return self;
}
public void setSelf(String self) {
this.self = self;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String key) {
this.description = description;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/*
public String[] getAvatarUrls() {
return avatarUrls;
}
public void setAvatarUrls(String[] avatarUrls) {
this.avatarUrls = avatarUrls;
}
*/
}
class JiraActors {
#SerializedName("id")
private int id;
#SerializedName("displayNme")
private String displayName;
#SerializedName("type")
private String type;
#SerializedName("name")
private String name;
//#SerializedName("avatarUrl")
//private String avatarUrl;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The json it would receive:
{
"self":"http://someserver.com:8080/apps/jira/rest/api/2/project/10741/role/10002",
"name":"Administrators",
"id":10002,
"description":"A project role",
"actors":[
{
"id":12432,
"displayName":"Joe Smith",
"type":"atlassian-user-role-actor",
"name":"joesmi",
"avatarUrl":"/apps/jira/secure/useravatar?size=xsmall&ownerId=dawsmi&avatarId=12245"
},
{
"id":12612,
"displayName":"Smurfette Desdemona",
"type":"atlassian-user-role-actor",
"name":"smudes",
"avatarUrl":"/apps/jira/secure/useravatar?size=xsmall&ownerId=lamade&avatarId=10100"
},
This shows two actors and the format of the json. Please note I did not put a complete json response. It just shows two actors.
In my code, I tried the following to retrieve the actors:
InputStream is = response.getEntityInputStream();
Reader reader = new InputStreamReader(is);
Gson gson = new Gson();
JiraRoleJsonWrapper[] jiraRoleJsonWrapper = gson.fromJson(reader, JiraRoleJsonWrapper[].class);
for (JiraRoleJsonWrapper w : jiraRoleJsonWrapper) {
JiraActors[] a = w.getActors();
String name = a.getName();
It does not find getName for some reason. I am not sure why.
I figured it out.
I change the setActors to
public void setActors(ArrayList<JiraActors> actors) {
this.actors = actors;
}
Then I was able to get the array list and get access to the getName() method of JiraActors.

How to write query in hibernate(HQL) to perform 2 joins without mapping?

I want to convert the following query into HQL:
SELECT C.ID, E.DESCRIPTION as STATUS, E1.DESCRIPTION as SUBJECT
FROM CRED C
join CODE_EVN E
ON E.CODE = C.STATUS_CODE
AND E.SUBCODE = C.STATUS_SUBCODE
join CODE_EVN E1
ON E1.CODE = C.SUBJECT_CODE
AND E1.SUBCODE = C.SUBJECT_SUBCODE
I have two classes User and Codes with no mapping in between them, so how do I execute the following query in Hibernate?
I have tried out many things but nothing seems to work
These are my 2 bean classes:
User class:
#Entity
#Table(name="CRED")
public class User {
private String id;
private String STATUS_CODE;
private String STATUS_SUBCODE;
private String SUBJECT_CODE;
private String SUBJECT_SUBCODE;
#Id
#Column(name="ID")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void setSTATUS_CODE(String sTATUS_CODE) {
STATUS_CODE = sTATUS_CODE;
}
public String getSTATUS_CODE() {
return STATUS_CODE;
}
public void setSTATUS_SUBCODE(String sTATUS_SUBCODE) {
STATUS_SUBCODE = sTATUS_SUBCODE;
}
public String getSTATUS_SUBCODE() {
return STATUS_SUBCODE;
}
public void setSUBJECT_CODE(String sUBJECT_CODE) {
SUBJECT_CODE = sUBJECT_CODE;
}
public String getSUBJECT_CODE() {
return SUBJECT_CODE;
}
public void setSUBJECT_SUBCODE(String sUBJECT_SUBCODE) {
SUBJECT_SUBCODE = sUBJECT_SUBCODE;
}
public String getSUBJECT_SUBCODE() {
return SUBJECT_SUBCODE;
}
}
Codes class:
#Entity
#Table(name="CODE_EVN")
public class Codes {
#Id
private String CODE;
private String SUBCODE;
private String DESCRIPTION;
public void setCODE(String cODE) {
CODE = cODE;
}
public String getCODE() {
return CODE;
}
public void setSUBCODE(String sUBCODE) {
SUBCODE = sUBCODE;
}
public String getSUBCODE() {
return SUBCODE;
}
public void setDESCRIPTION(String dESCRIPTION) {
DESCRIPTION = dESCRIPTION;
}
public String getDESCRIPTION() {
return DESCRIPTION;
}
}

Categories

Resources