org.hibernate.QueryException: could not resolve property - java

This is the first time that I use JPA. I write the code with Java and JPA. My code is below.
String queryStr = "SELECT m.title, b.isbn, b.authors";
queryStr += " FROM Book b, Media m";
queryStr += " WHERE m.MediaID = b.MediaID";
queryStr += " AND b.isbn = '" + isbn + "' AND m.title = '%" + title +"%'";
Query query = em.createQuery(queryStr);
From my code, Class Book extends class Media.
But I got the error which is
org.hibernate.QueryException: could not resolve property: MediaID of: mediaManagement.Media [SELECT m.title, b.isbn, b.authors FROM mediaManagement.Book b, mediaManagement.Media m WHERE m.MediaID = b.MediaID ]
This is the Media class.
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
#Table(name = "Media")
#NamedQuery(name = "findAllMedias", query = "select b from Media b")
public class Media {
#Id
#Column(name = "MediaID")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int mediaID;
/**
* Getter of the property <tt>mediaID</tt>
*
* #return Returns the mediaID.
* #uml.property name="mediaID"
*/
public int getMediaID() {
return mediaID;
}
/**
* Setter of the property <tt>mediaID</tt>
*
* #param mediaID
* The mediaID to set.
* #uml.property name="mediaID"
*/
public void setMediaID(int mediaID) {
this.mediaID = mediaID;
}
/**
* #uml.property name="title"
*/
#Column(name = "title")
private String title;
/**
* Getter of the property <tt>title</tt>
*
* #return Returns the title.
* #uml.property name="title"
*/
public String getTitle() {
return title;
}
/**
* Setter of the property <tt>title</tt>
*
* #param title
* The title to set.
* #uml.property name="title"
*/
public void setTitle(String title) {
this.title = title;
}
/**
* #uml.property name="editionDate"
*/
private Calendar editionDate;
/**
* Getter of the property <tt>editionDate</tt>
*
* #return Returns the editionDate.
* #uml.property name="editionDate"
*/
public Calendar getEditionDate() {
return editionDate;
}
/**
* Setter of the property <tt>editionDate</tt>
*
* #param editionDate
* The editionDate to set.
* #uml.property name="editionDate"
*/
public void setEditionDate(Calendar editionDate) {
this.editionDate = editionDate;
}
/*
* Two medias are equal if their mediaID is the same
*/
#Override
public boolean equals(Object media) {
if (media == null)
return false;
Media b = (Media) media;
if (b.mediaID == mediaID)
return true;
return false;
}
public Media() {
};
/**
* Creates a media All parameters should be given
*
* #param title
* the title of the media
*
* #param editionDate
* date of the edition of the media
*
* #throws BadParametersException
*/
public Media(String title, Calendar editionDate)
throws BadParametersException {
if ((title == null) || (editionDate == null))
throw new BadParametersException();
this.title = title;
this.editionDate = editionDate;
}
/**
* Returns a description of the media
*/
public String toString() {
return this.title + " " + String.valueOf(this.title);
}
/**
* #uml.property name="copies"
* #uml.associationEnd multiplicity="(0 -1)" inverse="media:copyManagement.Copy"
*/
#OneToMany(mappedBy="mediaRef") protected Set<Copy> copies;
public void addCopy(Copy copy) {
copies.add(copy);
}
/**
* Getter of the property <tt>copies</tt>
* #return Returns the copies.
* #uml.property name="copies"
*/
public Set<Copy> getCopies() {
return copies;
}
/**
* Setter of the property <tt>copies</tt>
* #param editionDate The copies to set.
* #uml.property name="copies"
*/
public void setCopies(Set<Copy> copies) {
this.copies = copies;
}
And this is Book class.
#Entity
#Table(name = "Book")
#NamedQuery(name = "findAllBooks", query = "select b from Book b")
public class Book extends Media {
/**
* #uml.property name="authors"
*/
#Column(name = "authors")
private ArrayList<String> authors;
/**
* Getter of the property <tt>authors</tt>
*
* #return Returns the authors.
* #uml.property name="authors"
*/
public ArrayList<String> getAuthors() {
return authors;
}
/**
* Setter of the property <tt>authors</tt>
*
* #param authors
* The authors to set.
* #uml.property name="authors"
*/
public void setAuthors(ArrayList<String> authors) {
this.authors = authors;
}
/**
* #uml.property name="isbn"
*/
#Column(name = "isbn")
private String isbn;
/**
* Getter of the property <tt>isbn</tt>
*
* #return Returns the isbn.
* #uml.property name="isbn"
*/
public String getisbn() {
return isbn;
}
/**
* Setter of the property <tt>isbn</tt>
*
* #param isbn
* The isbn to set.
* #uml.property name="isbn"
*/
public void setisbn(String isbn) {
this.isbn = isbn;
}
public Book() {
// TODO Auto-generated constructor stub
}
public Book(String title, Calendar editionDate, ArrayList<String> authors,
String isbn) throws BadParametersException {
super(title, editionDate);
this.authors = authors;
this.isbn = isbn;
// TODO Auto-generated constructor stub
}
}
Anyone can help?

If book extends media, why are you joining with the Media table? (though it would be easier with the Book and Media classes and mappings)
Querying the "Book" object should be enough. Also perhaps "MediaId" should be "mediaId". Hibernate is case sensitive on it's property names.

Related

Converting a json array to json object in android using gson?

I am passing a json array from activity A to activity B.Then I am using the GSON library to insert a value into the array.This is my current code.
public void gsonResponse(String json) {
try {
JSONObject jsonObject = new JSONObject(json);
JSONArray jsonArray = jsonObject.getJSONArray("result");
for (int i = 0; i < jsonArray.length(); i++) {
LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();
JSONObject innerJosonObject = new JSONObject(jsonArray.getString(i));
// you need to put all values from jsonObject to map for managing the order..
linkedHashMap.put("doc_no", textViewInvNo.getText().toString());
linkedHashMap.put("itembarcode", innerJosonObject.getString("itembarcode"));
linkedHashMap.put("net_wt", innerJosonObject.getString("net_wt"));
linkedHashMap.put("gross_wt", innerJosonObject.getString("gross_wt"));
linkedHashMap.put("stone_wt", innerJosonObject.getString("stone_wt"));
linkedHashMap.put("stone_amt", innerJosonObject.getString("stone_amt"));
linkedHashMap.put("rate", innerJosonObject.getString("rate"));
linkedHashMap.put("making", innerJosonObject.getString("making"));
linkedHashMap.put("qty", innerJosonObject.getString("qty"));
linkedHashMap.put("net_rate", innerJosonObject.getString("net_rate"));
linkedHashMap.put("item_total", innerJosonObject.getString("item_total"));
linkedHashMap.put("sum_total", innerJosonObject.getString("sum_total"));
Gson gson = new Gson();
// convert linkedHashMap to json string and it will keep the insertion order..
String string = gson.toJson(linkedHashMap, LinkedHashMap.class);
jsonArray.put(i, string);
}
jsonObject.put("result", jsonArray);
String jsonResp = jsonObject.toString();
jsonFormattedString = jsonResp.replaceAll("\\\\","");
Log.d("NEW JSON", jsonFormattedString);
} catch (JSONException e) {
e.printStackTrace();
}
}
The output for this is :-
{"result":["{"doc_no":"ES101","itembarcode":"BRMS","net_wt":"10","gross_wt":"1","stone_wt":"0","stone_amt":"0","rate":"32000","making":"100","qty":"1","net_rate":"32100.0","item_total":"32100.0","sum_total":"64600.0"}",
"{"doc_no":"ES101","itembarcode":"MSAA0015","net_wt":"10","gross_wt":"11","stone_wt":"100000","stone_amt":"1","rate":"32000","making":"500","qty":"1","net_rate":"32500.0","item_total":"32500.0","sum_total":"64600.0"}"]}
But my desired output should be something like :-
[{"doc_no":"IN1001","itembarcode":"BRMS123456\nFLT22K","net_wt":"10","gross_wt":"10","stone_amt":"0","rate":"29000","making":"999","qty":"1","net_rate":"29999.0","item_total":"29999.0","sum_total":"30299.0","stone_wt":"0"},
{"doc_no":"IN1001","itembarcode":"BRMS\nGA24K","net_wt":"10","gross_wt":"1","stone_amt":"0","rate":"32000","making":"100","qty":"1","net_rate":"","item_total":"","sum_total":"30299.0","stone_wt":""}]
How can I achieve it? Any suggestion or help is appreciated.Thank You.
Actually you don't need the following line:
jsonObject.put("result", jsonArray);
Just use the existing jsonArray like the following:
String jsonResp = jsonArray.toString();
One other note. you will get extra " " in your response and that is because of jsonArray.put(i, string); statement in the for loop which inserts extra " ". you can simply use the following to fix that:
jsonResp = jsonResp.replaceAll("\"[{]", "{");
jsonResp = jsonResp.replaceAll("[}]\"", "}");
Make a Model like This DocInfoModel.java ->
public class DocInfoModel {
#SerializedName("doc_no")
#Expose
private String docNo;
#SerializedName("itembarcode")
#Expose
private String itembarcode;
#SerializedName("net_wt")
#Expose
private String netWt;
#SerializedName("gross_wt")
#Expose
private String grossWt;
#SerializedName("stone_amt")
#Expose
private String stoneAmt;
#SerializedName("rate")
#Expose
private String rate;
#SerializedName("making")
#Expose
private String making;
#SerializedName("qty")
#Expose
private String qty;
#SerializedName("net_rate")
#Expose
private String netRate;
#SerializedName("item_total")
#Expose
private String itemTotal;
#SerializedName("sum_total")
#Expose
private String sumTotal;
#SerializedName("stone_wt")
#Expose
private String stoneWt;
/**
*
* #return
* The docNo
*/
public String getDocNo() {
return docNo;
}
/**
*
* #param docNo
* The doc_no
*/
public void setDocNo(String docNo) {
this.docNo = docNo;
}
/**
*
* #return
* The itembarcode
*/
public String getItembarcode() {
return itembarcode;
}
/**
*
* #param itembarcode
* The itembarcode
*/
public void setItembarcode(String itembarcode) {
this.itembarcode = itembarcode;
}
/**
*
* #return
* The netWt
*/
public String getNetWt() {
return netWt;
}
/**
*
* #param netWt
* The net_wt
*/
public void setNetWt(String netWt) {
this.netWt = netWt;
}
/**
*
* #return
* The grossWt
*/
public String getGrossWt() {
return grossWt;
}
/**
*
* #param grossWt
* The gross_wt
*/
public void setGrossWt(String grossWt) {
this.grossWt = grossWt;
}
/**
*
* #return
* The stoneAmt
*/
public String getStoneAmt() {
return stoneAmt;
}
/**
*
* #param stoneAmt
* The stone_amt
*/
public void setStoneAmt(String stoneAmt) {
this.stoneAmt = stoneAmt;
}
/**
*
* #return
* The rate
*/
public String getRate() {
return rate;
}
/**
*
* #param rate
* The rate
*/
public void setRate(String rate) {
this.rate = rate;
}
/**
*
* #return
* The making
*/
public String getMaking() {
return making;
}
/**
*
* #param making
* The making
*/
public void setMaking(String making) {
this.making = making;
}
/**
*
* #return
* The qty
*/
public String getQty() {
return qty;
}
/**
*
* #param qty
* The qty
*/
public void setQty(String qty) {
this.qty = qty;
}
/**
*
* #return
* The netRate
*/
public String getNetRate() {
return netRate;
}
/**
*
* #param netRate
* The net_rate
*/
public void setNetRate(String netRate) {
this.netRate = netRate;
}
/**
*
* #return
* The itemTotal
*/
public String getItemTotal() {
return itemTotal;
}
/**
*
* #param itemTotal
* The item_total
*/
public void setItemTotal(String itemTotal) {
this.itemTotal = itemTotal;
}
/**
*
* #return
* The sumTotal
*/
public String getSumTotal() {
return sumTotal;
}
/**
*
* #param sumTotal
* The sum_total
*/
public void setSumTotal(String sumTotal) {
this.sumTotal = sumTotal;
}
/**
*
* #return
* The stoneWt
*/
public String getStoneWt() {
return stoneWt;
}
/**
*
* #param stoneWt
* The stone_wt
*/
public void setStoneWt(String stoneWt) {
this.stoneWt = stoneWt;
}
}
And Parse the json by GSON ->
Gson gson = new Gson();
DocInfoModel[] docModel = gson.fromJson(RESPONSE_STRING,DocInfoModel[].class);
I would suggest to create Model class for your GSON implementation.
Check out this solution.
private void testDoc()
{
String json = "{\"result\":[{\"doc_no\":\"ES101\",\"itembarcode\":\"BRMS\",\"net_wt\":\"10\",\"gross_wt\":\"1\",\"stone_wt\":\"0\",\"stone_amt\":\"0\",\"rate\":\"32000\",\"making\":\"100\",\"qty\":\"1\",\"net_rate\":\"32100.0\",\"item_total\":\"32100.0\",\"sum_total\":\"64600.0\"},{\"doc_no\":\"ES101\",\"itembarcode\":\"MSAA0015\",\"net_wt\":\"10\",\"gross_wt\":\"11\",\"stone_wt\":\"100000\",\"stone_amt\":\"1\",\"rate\":\"32000\",\"making\":\"500\",\"qty\":\"1\",\"net_rate\":\"32500.0\",\"item_total\":\"32500.0\",\"sum_total\":\"64600.0\"}]}";
Gson gson = new Gson();
DocInfo docInfo = gson.fromJson(json, DocInfo.class);
System.out.println("Before ***********************");
System.out.println(gson.toJson(docInfo));
for(Result result : docInfo.getResult())
{
result.setDocNo("New Doc No");
}
System.out.println("After ***********************");
System.out.println(gson.toJson(docInfo));
}
DocInfo.java
import java.util.ArrayList;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class DocInfo {
#SerializedName("result")
#Expose
private List<Result> result = new ArrayList<Result>();
/**
*
* #return
* The result
*/
public List<Result> getResult() {
return result;
}
/**
*
* #param result
* The result
*/
public void setResult(List<Result> result) {
this.result = result;
}
}
Result.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Result {
#SerializedName("doc_no")
#Expose
private String docNo;
#SerializedName("itembarcode")
#Expose
private String itembarcode;
#SerializedName("net_wt")
#Expose
private String netWt;
#SerializedName("gross_wt")
#Expose
private String grossWt;
#SerializedName("stone_wt")
#Expose
private String stoneWt;
#SerializedName("stone_amt")
#Expose
private String stoneAmt;
#SerializedName("rate")
#Expose
private String rate;
#SerializedName("making")
#Expose
private String making;
#SerializedName("qty")
#Expose
private String qty;
#SerializedName("net_rate")
#Expose
private String netRate;
#SerializedName("item_total")
#Expose
private String itemTotal;
#SerializedName("sum_total")
#Expose
private String sumTotal;
/**
*
* #return
* The docNo
*/
public String getDocNo() {
return docNo;
}
/**
*
* #param docNo
* The doc_no
*/
public void setDocNo(String docNo) {
this.docNo = docNo;
}
/**
*
* #return
* The itembarcode
*/
public String getItembarcode() {
return itembarcode;
}
/**
*
* #param itembarcode
* The itembarcode
*/
public void setItembarcode(String itembarcode) {
this.itembarcode = itembarcode;
}
/**
*
* #return
* The netWt
*/
public String getNetWt() {
return netWt;
}
/**
*
* #param netWt
* The net_wt
*/
public void setNetWt(String netWt) {
this.netWt = netWt;
}
/**
*
* #return
* The grossWt
*/
public String getGrossWt() {
return grossWt;
}
/**
*
* #param grossWt
* The gross_wt
*/
public void setGrossWt(String grossWt) {
this.grossWt = grossWt;
}
/**
*
* #return
* The stoneWt
*/
public String getStoneWt() {
return stoneWt;
}
/**
*
* #param stoneWt
* The stone_wt
*/
public void setStoneWt(String stoneWt) {
this.stoneWt = stoneWt;
}
/**
*
* #return
* The stoneAmt
*/
public String getStoneAmt() {
return stoneAmt;
}
/**
*
* #param stoneAmt
* The stone_amt
*/
public void setStoneAmt(String stoneAmt) {
this.stoneAmt = stoneAmt;
}
/**
*
* #return
* The rate
*/
public String getRate() {
return rate;
}
/**
*
* #param rate
* The rate
*/
public void setRate(String rate) {
this.rate = rate;
}
/**
*
* #return
* The making
*/
public String getMaking() {
return making;
}
/**
*
* #param making
* The making
*/
public void setMaking(String making) {
this.making = making;
}
/**
*
* #return
* The qty
*/
public String getQty() {
return qty;
}
/**
*
* #param qty
* The qty
*/
public void setQty(String qty) {
this.qty = qty;
}
/**
*
* #return
* The netRate
*/
public String getNetRate() {
return netRate;
}
/**
*
* #param netRate
* The net_rate
*/
public void setNetRate(String netRate) {
this.netRate = netRate;
}
/**
*
* #return
* The itemTotal
*/
public String getItemTotal() {
return itemTotal;
}
/**
*
* #param itemTotal
* The item_total
*/
public void setItemTotal(String itemTotal) {
this.itemTotal = itemTotal;
}
/**
*
* #return
* The sumTotal
*/
public String getSumTotal() {
return sumTotal;
}
/**
*
* #param sumTotal
* The sum_total
*/
public void setSumTotal(String sumTotal) {
this.sumTotal = sumTotal;
}
}

Retrofit 2 (in Android) after implementation, Where are my JSON elements?

I'm implementing a retrofit 2 interface to parse JSON elements (video urls, thumbnails, title etc.)
JSONschema2Pojo resulted in 4 pojo classes, but the main/root one is VideoInfo (never mind implements Parcelable, I'm not yet doing anything with it)
Is the lack of #SerializedName("....") affects anything, knowing that this was automatically generated by jsonschema2pojo ? UPDATE : generated new pojo classes, this time with Gson annotations (#SerializedName("") and #Expose) but still having the same problem.
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
import java.util.List;
public class VideoInfo implements Parcelable {
private List<Item> items = new ArrayList<Item>();
private int pageNumber;
private int pageSize;
private int totalCount;
/**
* No args constructor for use in serialization
*
*/
public VideoInfo() {
}
/**
*
* #param totalCount
* #param items
* #param pageSize
* #param pageNumber
*/
public VideoInfo(List<Item> items, int pageNumber, int pageSize, int totalCount) {
this.items = items;
this.pageNumber = pageNumber;
this.pageSize = pageSize;
this.totalCount = totalCount;
}
/**
*
* #return
* The items
*/
public List<Item> getItems() {
return items;
}
/**
*
* #param items
* The items
*/
public void setItems(List<Item> items) {
this.items = items;
}
/**
*
* #return
* The pageNumber
*/
public int getPageNumber() {
return pageNumber;
}
/**
*
* #param pageNumber
* The page_number
*/
public void setPageNumber(int pageNumber) {
this.pageNumber = pageNumber;
}
/**
*
* #return
* The pageSize
*/
public int getPageSize() {
return pageSize;
}
/**
*
* #param pageSize
* The page_size
*/
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
/**
*
* #return
* The totalCount
*/
public int getTotalCount() {
return totalCount;
}
/**
*
* #param totalCount
* The total_count
*/
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
}
}
UPDATE: in the class VideoInfo above you can see private List<Item> items = new ArrayList<Item>(); this is because there's another pojo class that has a list of tiems, as follows:
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
public class Item {
#SerializedName("id")
#Expose
private int id;
#SerializedName("name")
#Expose
private String name;
#SerializedName("shortDescription")
#Expose
private String shortDescription;
#SerializedName("creationDate")
#Expose
private String creationDate;
#SerializedName("publishedDate")
#Expose
private String publishedDate;
#SerializedName("linkURL")
#Expose
private String linkURL;
#SerializedName("linkText")
#Expose
private String linkText;
#SerializedName("tags")
#Expose
private List<String> tags = new ArrayList<String>();
#SerializedName("videoStillURL")
#Expose
private String videoStillURL;
#SerializedName("thumbnailURL")
#Expose
private String thumbnailURL;
#SerializedName("length")
#Expose
private int length;
#SerializedName("renditions")
#Expose
private List<Rendition> renditions = new ArrayList<Rendition>();
#SerializedName("IOSRenditions")
#Expose
private List<IOSRendition> IOSRenditions = new ArrayList<IOSRendition>();
#SerializedName("HDSRenditions")
#Expose
private List<Object> HDSRenditions = new ArrayList<Object>();
/**
* No args constructor for use in serialization
*
*/
public Item() {
}
/**
*
* #param tags
* #param videoStillURL
* #param HDSRenditions
* #param id
* #param creationDate
* #param IOSRenditions
* #param linkText
* #param shortDescription
* #param renditions
* #param name
* #param linkURL
* #param length
* #param publishedDate
* #param thumbnailURL
*/
public Item(int id, String name, String shortDescription, String creationDate, String publishedDate, String linkURL, String linkText, List<String> tags, String videoStillURL, String thumbnailURL, int length, List<Rendition> renditions, List<IOSRendition> IOSRenditions, List<Object> HDSRenditions) {
this.id = id;
this.name = name;
this.shortDescription = shortDescription;
this.creationDate = creationDate;
this.publishedDate = publishedDate;
this.linkURL = linkURL;
this.linkText = linkText;
this.tags = tags;
this.videoStillURL = videoStillURL;
this.thumbnailURL = thumbnailURL;
this.length = length;
this.renditions = renditions;
this.IOSRenditions = IOSRenditions;
this.HDSRenditions = HDSRenditions;
}
/**
*
* #return
* The id
*/
public int getId() {
return id;
}
/**
*
* #param id
* The id
*/
public void setId(int id) {
this.id = id;
}
/**
*
* #return
* The name
*/
public String getName() {
return name;
}
/**
*
* #param name
* The name
*/
public void setName(String name) {
this.name = name;
}
/**
*
* #return
* The shortDescription
*/
public String getShortDescription() {
return shortDescription;
}
/**
*
* #param shortDescription
* The shortDescription
*/
public void setShortDescription(String shortDescription) {
this.shortDescription = shortDescription;
}
/**
*
* #return
* The creationDate
*/
public String getCreationDate() {
return creationDate;
}
/**
*
* #param creationDate
* The creationDate
*/
public void setCreationDate(String creationDate) {
this.creationDate = creationDate;
}
/**
*
* #return
* The publishedDate
*/
public String getPublishedDate() {
return publishedDate;
}
/**
*
* #param publishedDate
* The publishedDate
*/
public void setPublishedDate(String publishedDate) {
this.publishedDate = publishedDate;
}
/**
*
* #return
* The linkURL
*/
public String getLinkURL() {
return linkURL;
}
/**
*
* #param linkURL
* The linkURL
*/
public void setLinkURL(String linkURL) {
this.linkURL = linkURL;
}
/**
*
* #return
* The linkText
*/
public String getLinkText() {
return linkText;
}
/**
*
* #param linkText
* The linkText
*/
public void setLinkText(String linkText) {
this.linkText = linkText;
}
/**
*
* #return
* The tags
*/
public List<String> getTags() {
return tags;
}
/**
*
* #param tags
* The tags
*/
public void setTags(List<String> tags) {
this.tags = tags;
}
/**
*
* #return
* The videoStillURL
*/
public String getVideoStillURL() {
return videoStillURL;
}
/**
*
* #param videoStillURL
* The videoStillURL
*/
public void setVideoStillURL(String videoStillURL) {
this.videoStillURL = videoStillURL;
}
/**
*
* #return
* The thumbnailURL
*/
public String getThumbnailURL() {
return thumbnailURL;
}
/**
*
* #param thumbnailURL
* The thumbnailURL
*/
public void setThumbnailURL(String thumbnailURL) {
this.thumbnailURL = thumbnailURL;
}
/**
*
* #return
* The length
*/
public int getLength() {
return length;
}
/**
*
* #param length
* The length
*/
public void setLength(int length) {
this.length = length;
}
/**
*
* #return
* The renditions
*/
public List<Rendition> getRenditions() {
return renditions;
}
/**
*
* #param renditions
* The renditions
*/
public void setRenditions(List<Rendition> renditions) {
this.renditions = renditions;
}
/**
*
* #return
* The IOSRenditions
*/
public List<IOSRendition> getIOSRenditions() {
return IOSRenditions;
}
/**
*
* #param IOSRenditions
* The IOSRenditions
*/
public void setIOSRenditions(List<IOSRendition> IOSRenditions) {
this.IOSRenditions = IOSRenditions;
}
/**
*
* #return
* The HDSRenditions
*/
public List<Object> getHDSRenditions() {
return HDSRenditions;
}
/**
*
* #param HDSRenditions
* The HDSRenditions
*/
public void setHDSRenditions(List<Object> HDSRenditions) {
this.HDSRenditions = HDSRenditions;
}
}
UPDATE: So above you can see that we have defined private List<Rendition> renditions = new ArrayList<Rendition>(); that is defined in another pojo classes Rendition.class:
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Rendition {
#SerializedName("audioOnly")
#Expose
private boolean audioOnly;
#SerializedName("controllerType")
#Expose
private String controllerType;
#SerializedName("displayName")
#Expose
private String displayName;
#SerializedName("encodingRate")
#Expose
private int encodingRate;
#SerializedName("frameHeight")
#Expose
private int frameHeight;
#SerializedName("frameWidth")
#Expose
private int frameWidth;
#SerializedName("id")
#Expose
private int id;
#SerializedName("referenceId")
#Expose
private Object referenceId;
#SerializedName("remoteStreamName")
#Expose
private Object remoteStreamName;
#SerializedName("remoteUrl")
#Expose
private Object remoteUrl;
#SerializedName("size")
#Expose
private int size;
#SerializedName("uploadTimestampMillis")
#Expose
private int uploadTimestampMillis;
#SerializedName("url")
#Expose
private String url;
#SerializedName("videoCodec")
#Expose
private String videoCodec;
#SerializedName("videoContainer")
#Expose
private String videoContainer;
#SerializedName("videoDuration")
#Expose
private int videoDuration;
/**
* No args constructor for use in serialization
*
*/
public Rendition() {
}
/**
*
* #param controllerType
* #param encodingRate
* #param referenceId
* #param url
* #param size
* #param id
* #param uploadTimestampMillis
* #param frameWidth
* #param remoteUrl
* #param videoContainer
* #param remoteStreamName
* #param displayName
* #param videoCodec
* #param videoDuration
* #param audioOnly
* #param frameHeight
*/
public Rendition(boolean audioOnly, String controllerType, String displayName, int encodingRate, int frameHeight, int frameWidth, int id, Object referenceId, Object remoteStreamName, Object remoteUrl, int size, int uploadTimestampMillis, String url, String videoCodec, String videoContainer, int videoDuration) {
this.audioOnly = audioOnly;
this.controllerType = controllerType;
this.displayName = displayName;
this.encodingRate = encodingRate;
this.frameHeight = frameHeight;
this.frameWidth = frameWidth;
this.id = id;
this.referenceId = referenceId;
this.remoteStreamName = remoteStreamName;
this.remoteUrl = remoteUrl;
this.size = size;
this.uploadTimestampMillis = uploadTimestampMillis;
this.url = url;
this.videoCodec = videoCodec;
this.videoContainer = videoContainer;
this.videoDuration = videoDuration;
}
/**
*
* #return
* The audioOnly
*/
public boolean isAudioOnly() {
return audioOnly;
}
/**
*
* #param audioOnly
* The audioOnly
*/
public void setAudioOnly(boolean audioOnly) {
this.audioOnly = audioOnly;
}
/**
*
* #return
* The controllerType
*/
public String getControllerType() {
return controllerType;
}
/**
*
* #param controllerType
* The controllerType
*/
public void setControllerType(String controllerType) {
this.controllerType = controllerType;
}
/**
*
* #return
* The displayName
*/
public String getDisplayName() {
return displayName;
}
/**
*
* #param displayName
* The displayName
*/
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
/**
*
* #return
* The encodingRate
*/
public int getEncodingRate() {
return encodingRate;
}
/**
*
* #param encodingRate
* The encodingRate
*/
public void setEncodingRate(int encodingRate) {
this.encodingRate = encodingRate;
}
/**
*
* #return
* The frameHeight
*/
public int getFrameHeight() {
return frameHeight;
}
/**
*
* #param frameHeight
* The frameHeight
*/
public void setFrameHeight(int frameHeight) {
this.frameHeight = frameHeight;
}
/**
*
* #return
* The frameWidth
*/
public int getFrameWidth() {
return frameWidth;
}
/**
*
* #param frameWidth
* The frameWidth
*/
public void setFrameWidth(int frameWidth) {
this.frameWidth = frameWidth;
}
/**
*
* #return
* The id
*/
public int getId() {
return id;
}
/**
*
* #param id
* The id
*/
public void setId(int id) {
this.id = id;
}
/**
*
* #return
* The referenceId
*/
public Object getReferenceId() {
return referenceId;
}
/**
*
* #param referenceId
* The referenceId
*/
public void setReferenceId(Object referenceId) {
this.referenceId = referenceId;
}
/**
*
* #return
* The remoteStreamName
*/
public Object getRemoteStreamName() {
return remoteStreamName;
}
/**
*
* #param remoteStreamName
* The remoteStreamName
*/
public void setRemoteStreamName(Object remoteStreamName) {
this.remoteStreamName = remoteStreamName;
}
/**
*
* #return
* The remoteUrl
*/
public Object getRemoteUrl() {
return remoteUrl;
}
/**
*
* #param remoteUrl
* The remoteUrl
*/
public void setRemoteUrl(Object remoteUrl) {
this.remoteUrl = remoteUrl;
}
/**
*
* #return
* The size
*/
public int getSize() {
return size;
}
/**
*
* #param size
* The size
*/
public void setSize(int size) {
this.size = size;
}
/**
*
* #return
* The uploadTimestampMillis
*/
public int getUploadTimestampMillis() {
return uploadTimestampMillis;
}
/**
*
* #param uploadTimestampMillis
* The uploadTimestampMillis
*/
public void setUploadTimestampMillis(int uploadTimestampMillis) {
this.uploadTimestampMillis = uploadTimestampMillis;
}
/**
*
* #return
* The url
*/
public String getUrl() {
return url;
}
/**
*
* #param url
* The url
*/
public void setUrl(String url) {
this.url = url;
}
/**
*
* #return
* The videoCodec
*/
public String getVideoCodec() {
return videoCodec;
}
/**
*
* #param videoCodec
* The videoCodec
*/
public void setVideoCodec(String videoCodec) {
this.videoCodec = videoCodec;
}
/**
*
* #return
* The videoContainer
*/
public String getVideoContainer() {
return videoContainer;
}
/**
*
* #param videoContainer
* The videoContainer
*/
public void setVideoContainer(String videoContainer) {
this.videoContainer = videoContainer;
}
/**
*
* #return
* The videoDuration
*/
public int getVideoDuration() {
return videoDuration;
}
/**
*
* #param videoDuration
* The videoDuration
*/
public void setVideoDuration(int videoDuration) {
this.videoDuration = videoDuration;
}
}
I have created a retrofit interface VideoInterface.class
import retrofit2.Call;
import retrofit2.http.GET;
/**
* retrofit 2 interface
*/
public interface VideoInterface {
String apiURL = ".....";
#GET(apiURL)
public Call<VideosResponse> listVideos();
}
I have created a response/parse class VideosResponse.java
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.ArrayList;
import java.util.List;
/**
*/
public class VideosResponse {
//initalizing the collection
List<VideoInfo> videos;
public VideosResponse() {
videos = new ArrayList<VideoInfo>();
}
//parsing the response
public static VideosResponse parseJSON(String response) {
Gson gson = new GsonBuilder().create();
VideosResponse videosResponse = gson.fromJson(response, VideosResponse.class);
return videosResponse;
}
}
UPDATED :Finally I'm calling the API , but not able to get the individual elements
I know I should be able to do something like response.body().getItem().getID().getRendition().getUrl() for example, but I don't see it in the auto complete and if I write it I get errors.
This code is in my onResume() method , the reason why I've commented out public static below is because it's not allowed within the onResume()
// Creating a simple REST adapter which points the API
// public static
final String BASE_URL = "http://api......";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
// Creating an instance of our API interface.
VideoInterface service = retrofit.create(VideoInterface.class);
Call<VideosResponse> call = service.listVideos();
call.enqueue(new Callback<VideosResponse>() {
#Override
public void onResponse(Call<VideosResponse> call, Response<VideosResponse> response) {
VideosResponse videoResponse = response.body();
}
#Override
public void onFailure(Call<VideosResponse> call, Throwable t) {
}});
Everything to the last step seems be alright (no errors), the following logs gives me:
Log.d("Videos ", response.message()); //OK
Log.d("Videos ", String.valueOf(response.isSuccess())); //TRUE
Log.d("Videos ", String.valueOf(response.code())); //200
but I'm still not able to get the strings I need. When I print the log for the response show the response VideosResponse videoResponse = response.body(); I get : VideosResponse#3b8bfaa4 , is this normal? how can I use this?
Is using parcelable advised? will it change anything?
You need to show us the json response or you can figure out on your own also. Basically the object attributes name must match the json attributes, you can debug to see whether the elements are receiving the value or not, in case they are not then add the SerializedName annotation to it. From there onwards there are two possibilities either you have an object or an array. For which you can further create a POJO or create a attribute of type List.
I know I should be able to do something like response.body().item.getID() for example
Um, no, not based on the code as I understand it.
response here would appear to be Response<VideosResponse> response
response.body() therefore would be a VideosResponse
response.body().item will fail, as VideosResponse does not have an item field
When I print the log for the response show the response VideosResponse videoResponse = response.body(); I get : VideosResponse#3b8bfaa4 , is this normal?
Yes. That is the default toString() output for a Java object that has not overridden toString(). This shows that response.body() is a VideosResponse.
I have created a response/parse class VideosResponse.java
Then you know that VideosResponse does not have anything named item. Gson does not add methods to your classes; it only populates instances of those classes, based on parsing some JSON.
If you are expecting VideosResponse to have an item field, make sure that exists in your JSON, and then edit VideosResponse to have an item field.
add a toString() to your VideoInfo class and then onResponse you can log the single object of the returned list with something like
for (VideoInfo videoInfo : videoResponses)
Log.d(LOG_TAG, "VideoInfo: " + videoInfo.toString());

Expected BEGIN_OBJECT but was STRING with custom TypeAdapter

So I'm trying to solve a problem that I have with my custom TypeAdapter with Gson and Retrofit. I keep getting a Expected BEGIN_OBJECT but was STRING error but I'm not really sure how to solve it. Previously I was getting a Expected BEGIN_ARRAY but was STRING error and I solved that. I'm not sure if it needs to be the same way with this new error. I've listed my classes below and any help is appreciated. This is what my json looks like here: http://pastie.org/private/bfo86iznldacbz10rtsdsg The main problem is the multimedia field in the json. It's an empty string if there is no value but if there is a value, it returns a jsonarray that contains jsonobjects.
ArrayAdapter.java
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
public class ArrayAdapter<T> extends TypeAdapter<List<T>> {
private Class<T> adapterclass;
public ArrayAdapter(Class<T> adapterclass) {
this.adapterclass = adapterclass;
}
public List<T> read(JsonReader reader) throws IOException {
List<T> list = new ArrayList<T>();
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(new ArrayAdapterFactory())
.create();
if (reader.peek() == JsonToken.STRING) {
T inning = gson.fromJson(reader, adapterclass);
list.add(inning);
} else if (reader.peek() == JsonToken.BEGIN_ARRAY) {
reader.beginArray();
while (reader.hasNext()) {
T inning = gson.fromJson(reader, adapterclass);
list.add(inning);
}
reader.endArray();
} else if (reader.peek() == JsonToken.BEGIN_OBJECT) {
reader.beginObject();
while(reader.hasNext()) {
}
}
return list;
}
public void write(JsonWriter writer, List<T> value) throws IOException {
}
}
ArraryAdapterFactory
import java.lang.reflect.ParameterizedType;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
public class ArrayAdapterFactory implements TypeAdapterFactory {
#SuppressWarnings({ "unchecked", "rawtypes" })
#Override
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {
TypeAdapter<T> typeAdapter = null;
try {
if (type.getRawType() == List.class)
typeAdapter = new ArrayAdapter(
(Class) ((ParameterizedType) type.getType())
.getActualTypeArguments()[0]);
} catch (Exception e) {
e.printStackTrace();
}
return typeAdapter;
}
}
Times.java
public class NYTimes {
// uses the new york times api
// gets the top stores on the nytimes homepage
private static final String API_URL = "http://api.nytimes.com/svc/news/v3/content/all/all";
static Gson gson = new GsonBuilder().registerTypeAdapterFactory(new ArrayAdapterFactory()).create();
private static final RestAdapter REST_ADAPTER = new RestAdapter.Builder()
.setConverter(new GsonConverter(gson))
.setEndpoint(API_URL)
.build();
private static final NYTimesService SERVICE = REST_ADAPTER.create(NYTimesService.class);
public static NYTimesService getService() {
return SERVICE;
}
}
POJO Classes
News.java
public class News {
#Expose
private String status;
#Expose
private String copyright;
#SerializedName("num_results")
#Expose
private Integer numResults;
#Expose
private List<Result> results = new ArrayList<Result>();
/**
*
* #return
* The status
*/
public String getStatus() {
return status;
}
/**
*
* #param status
* The status
*/
public void setStatus(String status) {
this.status = status;
}
/**
*
* #return
* The copyright
*/
public String getCopyright() {
return copyright;
}
/**
*
* #param copyright
* The copyright
*/
public void setCopyright(String copyright) {
this.copyright = copyright;
}
/**
*
* #return
* The numResults
*/
public Integer getNumResults() {
return numResults;
}
/**
*
* #param numResults
* The num_results
*/
public void setNumResults(Integer numResults) {
this.numResults = numResults;
}
/**
*
* #return
* The results
*/
public List<Result> getResults() {
return results;
}
/**
*
* #param results
* The results
*/
public void setResults(List<Result> results) {
this.results = results;
}
}
Result.java
public class Result {
#Expose
private String section;
#Expose
private String subsection;
#Expose
private String title;
#SerializedName("abstract")
#Expose
private String _abstract;
#Expose
private String url;
#Expose
private String byline;
#SerializedName("thumbnail_standard")
#Expose
private String thumbnailStandard;
#SerializedName("item_type")
#Expose
private String itemType;
#Expose
private String source;
#SerializedName("updated_date")
#Expose
private String updatedDate;
#SerializedName("created_date")
#Expose
private String createdDate;
#SerializedName("published_date")
#Expose
private String publishedDate;
#SerializedName("material_type_facet")
#Expose
private String materialTypeFacet;
#Expose
private String kicker;
#Expose
private String subheadline;
#SerializedName("des_facet")
#Expose
private List<String> desFacet = new ArrayList<>();
#SerializedName("org_facet")
#Expose
private List<String> orgFacet = new ArrayList<>();
#SerializedName("per_facet")
#Expose
private List<String> perFacet = new ArrayList<>();
#SerializedName("geo_facet")
#Expose
private List<String> geoFacet = new ArrayList<>();
#SerializedName("related_urls")
#Expose
private Object relatedUrls;
#Expose
private List<Multimedium> multimedia;
/**
*
* #return
* The section
*/
public String getSection() {
return section;
}
/**
*
* #param section
* The section
*/
public void setSection(String section) {
this.section = section;
}
/**
*
* #return
* The subsection
*/
public String getSubsection() {
return subsection;
}
/**
*
* #param subsection
* The subsection
*/
public void setSubsection(String subsection) {
this.subsection = subsection;
}
/**
*
* #return
* The title
*/
public String getTitle() {
return title;
}
/**
*
* #param title
* The title
*/
public void setTitle(String title) {
this.title = title;
}
/**
*
* #return
* The _abstract
*/
public String getAbstract() {
return _abstract;
}
/**
*
* #param _abstract
* The abstract
*/
public void setAbstract(String _abstract) {
this._abstract = _abstract;
}
/**
*
* #return
* The url
*/
public String getUrl() {
return url;
}
/**
*
* #param url
* The url
*/
public void setUrl(String url) {
this.url = url;
}
/**
*
* #return
* The byline
*/
public String getByline() {
return byline;
}
/**
*
* #param byline
* The byline
*/
public void setByline(String byline) {
this.byline = byline;
}
/**
*
* #return
* The thumbnailStandard
*/
public String getThumbnailStandard() {
return thumbnailStandard;
}
/**
*
* #param thumbnailStandard
* The thumbnail_standard
*/
public void setThumbnailStandard(String thumbnailStandard) {
this.thumbnailStandard = thumbnailStandard;
}
/**
*
* #return
* The itemType
*/
public String getItemType() {
return itemType;
}
/**
*
* #param itemType
* The item_type
*/
public void setItemType(String itemType) {
this.itemType = itemType;
}
/**
*
* #return
* The source
*/
public String getSource() {
return source;
}
/**
*
* #param source
* The source
*/
public void setSource(String source) {
this.source = source;
}
/**
*
* #return
* The updatedDate
*/
public String getUpdatedDate() {
return updatedDate;
}
/**
*
* #param updatedDate
* The updated_date
*/
public void setUpdatedDate(String updatedDate) {
this.updatedDate = updatedDate;
}
/**
*
* #return
* The createdDate
*/
public String getCreatedDate() {
return createdDate;
}
/**
*
* #param createdDate
* The created_date
*/
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}
/**
*
* #return
* The publishedDate
*/
public String getPublishedDate() {
return publishedDate;
}
/**
*
* #param publishedDate
* The published_date
*/
public void setPublishedDate(String publishedDate) {
this.publishedDate = publishedDate;
}
/**
*
* #return
* The materialTypeFacet
*/
public String getMaterialTypeFacet() {
return materialTypeFacet;
}
/**
*
* #param materialTypeFacet
* The material_type_facet
*/
public void setMaterialTypeFacet(String materialTypeFacet) {
this.materialTypeFacet = materialTypeFacet;
}
/**
*
* #return
* The kicker
*/
public String getKicker() {
return kicker;
}
/**
*
* #param kicker
* The kicker
*/
public void setKicker(String kicker) {
this.kicker = kicker;
}
/**
*
* #return
* The subheadline
*/
public String getSubheadline() {
return subheadline;
}
/**
*
* #param subheadline
* The subheadline
*/
public void setSubheadline(String subheadline) {
this.subheadline = subheadline;
}
/**
*
* #return
* The desFacet
*/
public List<String> getDesFacet() {
return desFacet;
}
/**
*
* #param desFacet
* The des_facet
*/
public void setDesFacet(List<String> desFacet) {
this.desFacet = desFacet;
}
/**
*
* #return
* The orgFacet
*/
public List<String> getOrgFacet() {
return orgFacet;
}
/**
*
* #param orgFacet
* The org_facet
*/
public void setOrgFacet(List<String> orgFacet) {
this.orgFacet = orgFacet;
}
/**
*
* #return
* The perFacet
*/
public List<String> getPerFacet() {
return perFacet;
}
/**
*
* #param perFacet
* The per_facet
*/
public void setPerFacet(List<String> perFacet) {
this.perFacet = perFacet;
}
/**
*
* #return
* The geoFacet
*/
public List<String> getGeoFacet() {
return geoFacet;
}
/**
*
* #param geoFacet
* The geo_facet
*/
public void setGeoFacet(List<String> geoFacet) {
this.geoFacet = geoFacet;
}
/**
*
* #return
* The relatedUrls
*/
public Object getRelatedUrls() {
return relatedUrls;
}
/**
*
* #param relatedUrls
* The related_urls
*/
public void setRelatedUrls(Object relatedUrls) {
this.relatedUrls = relatedUrls;
}
/**
*
* #return
* The multimedia
*/
public List<Multimedium> getMultimedia() {
return multimedia;
}
/**
*
* #param multimedia
* The multimedia
*/
public void setMultimedia(List<Multimedium> multimedia) {
this.multimedia = multimedia;
}
}
Multimedium.java
public class Multimedium {
#Expose
private String url;
#Expose
private String format;
#Expose
private Integer height;
#Expose
private Integer width;
#Expose
private String type;
#Expose
private String subtype;
#Expose
private Object caption;
#Expose
private Object copyright;
/**
*
* #return
* The url
*/
public String getUrl() {
return url;
}
/**
*
* #param url
* The url
*/
public void setUrl(String url) {
this.url = url;
}
/**
*
* #return
* The format
*/
public String getFormat() {
return format;
}
/**
*
* #param format
* The format
*/
public void setFormat(String format) {
this.format = format;
}
/**
*
* #return
* The height
*/
public Integer getHeight() {
return height;
}
/**
*
* #param height
* The height
*/
public void setHeight(Integer height) {
this.height = height;
}
/**
*
* #return
* The width
*/
public Integer getWidth() {
return width;
}
/**
*
* #param width
* The width
*/
public void setWidth(Integer width) {
this.width = width;
}
/**
*
* #return
* The type
*/
public String getType() {
return type;
}
/**
*
* #param type
* The type
*/
public void setType(String type) {
this.type = type;
}
/**
*
* #return
* The subtype
*/
public String getSubtype() {
return subtype;
}
/**
*
* #param subtype
* The subtype
*/
public void setSubtype(String subtype) {
this.subtype = subtype;
}
/**
*
* #return
* The caption
*/
public Object getCaption() {
return caption;
}
/**
*
* #param caption
* The caption
*/
public void setCaption(Object caption) {
this.caption = caption;
}
/**
*
* #return
* The copyright
*/
public Object getCopyright() {
return copyright;
}
/**
*
* #param copyright
* The copyright
*/
public void setCopyright(Object copyright) {
this.copyright = copyright;
}
}
I know it's a lot of code to go through but I'm looking for any help to solve this problem so I'm trying to be as clear as I can.
I was able to get a solution by implementing a custom JsonDeserializer and then adding that to the RestAdapter like so:
public class ResultsDeserializerJson implements JsonDeserializer<Result> {
#Override
public Result deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonElement titleElement = json.getAsJsonObject().get("title");
JsonElement multimediaElement = json.getAsJsonObject().get("multimedia");
if (multimediaElement.isJsonArray()) {
return new Result(
titleElement.toString(),
(Multimedia[]) context.deserialize(multimediaElement.getAsJsonArray(), Multimedia[].class));
} else if (multimediaElement.getAsString().equals("")) {
Multimedia multimedia = new Multimedia();
multimedia.setFormat("");
multimedia.setUrl("");
return new Result(titleElement.toString(), multimedia);
} else {
Log.d("ResultsDeserializerJson", multimediaElement.toString());
throw new JsonParseException("Unsupported type of multimedia element");
}
}
}
Inside Result.java I added the following constructor (note you can add more parameters for things like section, subsection, etc.):
public Result(String title, Multimedia ... multimedia) {
this.mTitle = title.replace("\"", "");;
mMultimedia = Arrays.asList(multimedia);
}
Then for my RestAdapter I do the following:
private NYTimesService() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Result.class, new ResultsDeserializerJson()).create();
mAsyncRestAdapter = new RestAdapter.Builder()
.setEndpoint(API_URL)
.setConverter(new GsonConverter(gson))
.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
request.addEncodedQueryParam("api-key", API_KEY);
}
})
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
}
I created a custom application to get this working and the repository is open sourced here:
SampleNYTimesApp Repo
This is still somewhat of a hackish solution, and I feel like it is not the most optimal, but I was able to get the following in the time I figured out the solution:

Hibernate many to many selects wrong column

SOLVED: I had an error at the place where I called for the getAllergies! There is nothing wrong with this setup.
I'm currently working on a project involving Spring and Hibernate and got an issue with a ManyToMany relation.
These are the java classes:
Patient.java
package medicapp.models.impl;
import javax.persistence.*;
import java.sql.Date;
import java.util.List;
#Entity
#Table(name="patient")
public class Patient {
#Id
#Column(name="Id")
private int id;
#Column(name="NatNumber")
private String nationalNumber;
#Column(name="FirstName")
private String firstName;
#Column(name="LastName")
private String lastName;
#Column(name="Address")
private String address;
#ManyToOne(cascade = {CascadeType.ALL})
#JoinColumn(name="birthplace")
private Municipality birthPlace;
#ManyToOne(cascade = {CascadeType.ALL})
#JoinColumn(name="zipcode")
private Municipality municipality;
#ManyToOne(cascade = {CascadeType.ALL})
#JoinColumn(name="healthinsuranceid")
private HealthInsurance healthInsurance;
#Column(name="Nationality")
private String nationality;
#Column(name="ContactName")
private String contactName;
#Column(name="ContactNumber")
private String contactNumber;
#Column(name="Phone")
private String phone;
#Column(name="Email")
private String email;
#Column(name="Gender")
private char gender;
#Column(name="DateOfBirth")
private Date birthDate;
#Column(name="Smoker")
private boolean smoker;
// Geen Idee hoe we dat gaan doen, effe opgelost door transient te gebruiken, moet nog worden gecheckt
#ManyToOne(cascade = {CascadeType.ALL})
#JoinColumn(name="bloodgroupid")
private BloodType bloodType;
#ManyToOne(cascade = {CascadeType.ALL})
#JoinColumn(name="juridicalid")
private Juridical juridical;
#ManyToMany
#JoinTable(name = "allergypatient",
joinColumns = #JoinColumn(name="PatientId"),
inverseJoinColumns = #JoinColumn(name = "AllergyId")
)
private List<Allergy> allergies;
#ManyToMany
#JoinTable(name = "medicationpatient",
joinColumns = #JoinColumn(name="PatientId"),
inverseJoinColumns = #JoinColumn(name = "MedicationId")
)
//#Transient
private List<Medication> medications;
#ManyToMany
#JoinTable(name = "chronicdiseasepatient",
joinColumns = #JoinColumn(name="PatientId"),
inverseJoinColumns = #JoinColumn(name = "ChronicDiseaseId")
)
//#Transient
private List<Disease> diseases;
#ManyToMany
#JoinTable(name = "vaccinationpatient",
joinColumns = #JoinColumn(name="PatientId"),
inverseJoinColumns = #JoinColumn(name = "VaccinationId")
)
//#Transient
private List<Vaccination> vaccinations;
#Column(name="lastwill")
private boolean lastWill;
/**
*
* #param id
* #param nationalNumber
* #param firstName
* #param lastName
* #param address
* #param birthPlace
* #param municipality
* #param healthInsurance
* #param nationality
* #param gender
* #param birthDate
*/
public Patient(int id, String nationalNumber, String firstName, String lastName, String address, Municipality birthPlace, Municipality municipality, HealthInsurance healthInsurance, String nationality, char gender, Date birthDate) {
this.id = id;
this.nationalNumber = nationalNumber;
this.firstName = firstName;
this.lastName = lastName;
this.address = address;
this.birthPlace = birthPlace;
this.municipality = municipality;
this.healthInsurance = healthInsurance;
this.nationality = nationality;
this.gender = gender;
this.birthDate = birthDate;
}
/**
* Default Constructor without parameters, this is required for using Hibernate
*/
public Patient() {
}
/**
* #param firstName
* #param lastName
* #param address
* #param municipality
* #param birthDate Patient constructor with the minum required values
*/
public Patient(String firstName, String lastName, String address, Municipality municipality, Date birthDate) {
this.firstName = firstName;
this.address = address;
this.municipality = municipality;
this.lastName = lastName;
this.birthDate = birthDate;
}
public Patient(String firstName, String lastName, String address,Date birthDate){
this.firstName = firstName;
this.address = address;
this.lastName = lastName;
this.birthDate = birthDate;
}
public Patient(String firstName, String lastName, String address, Municipality municipality, Municipality birthPlace, String nationalNumber, String nationality, char gender, Date birthDate, String phone, String email, Boolean smoker, Juridical juridical, BloodType bloodType, HealthInsurance healthInsurance, String contactName, String contactNumber, boolean lastWill) {
this.address = address;
this.birthDate = birthDate;
this.birthPlace = birthPlace;
this.firstName = firstName;
this.gender = gender;
this.lastName = lastName;
this.nationality = nationality;
this.nationalNumber = nationalNumber;
this.municipality = municipality;
this.juridical = juridical;
this.lastWill = lastWill;
this.healthInsurance = healthInsurance;
this.bloodType = bloodType;
this.phone = phone;
this.email = email;
this.smoker = smoker;
this.contactName = contactName;
this.contactNumber = contactNumber;
}
/**
* #param firstName
* #param lastName
* #param address
* #param municipality
* #param birthPlace
* #param nationalNumber
* #param nationality
* #param gender
* #param birthDate
* Patient constructor that uses all the values retrieved from the e-ID
* #author Geert Peters
*/
public Patient(String firstName, String lastName, String address, Municipality municipality, Municipality birthPlace, String nationalNumber, String nationality, char gender, Date birthDate) {
this.address = address;
this.birthDate = birthDate;
this.birthPlace = birthPlace;
this.firstName = firstName;
this.gender = gender;
this.lastName = lastName;
this.nationality = nationality;
this.nationalNumber = nationalNumber;
this.municipality = municipality;
}
/**
* #param allergy adds an allergy to a patient's file
*/
public void addAllergy(Allergy allergy) {
this.allergies.add(allergy);
}
/**
* #param disease adds a disease to a patient's file
*/
public void addDisease(Disease disease) {
this.diseases.add(disease);
}
/**
* #param medication adds a medication to a patient's file
*/
public void addMedication(Medication medication) {
this.medications.add(medication);
}
/**
* #param vaccination adds a vaccination to a patient's file
*/
public void addVaccination(Vaccination vaccination) {
this.vaccinations.add(vaccination);
}
/**
* #param medication removes a medication from the list
*/
public void removeMedication(Medication medication) {
this.medications.remove(medication);
}
/**
* Gets smoker.
*
* #return Value of smoker.
*/
public boolean isSmoker() {
return smoker;
}
/**
* Gets birthPlace.
*
* #return Value of birthPlace.
*/
public Municipality getBirthPlace() {
return birthPlace;
}
/**
* Sets new id.
*
* #param id New value of id.
*/
public void setId(int id) {
this.id = id;
}
/**
* Sets new smoker.
*
* #param smoker New value of smoker.
*/
public void setSmoker(boolean smoker) {
this.smoker = smoker;
}
/**
* Gets id.
*
* #return Value of id.
*/
public int getId() {
return id;
}
/**
* Gets address.
*
* #return Value of address.
*/
public String getAddress() {
return address;
}
/**
* Sets new lastName.
*
* #param lastName New value of lastName.
*/
public void setLastName(String lastName) {
this.lastName = lastName;
}
/**
* Gets gender.
*
* #return Value of gender.
*/
public char getGender() {
return gender;
}
/**
* Gets nationalNumber.
*
* #return Value of nationalNumber.
*/
public String getNationalNumber() {
return nationalNumber;
}
/**
* Gets firstName.
*
* #return Value of firstName.
*/
public String getFirstName() {
return firstName;
}
/**
* Gets municipality.
*
* #return Value of municipality.
*/
public Municipality getMunicipality() {
return municipality;
}
/**
* Sets new nationalNumber.
*
* #param nationalNumber New value of nationalNumber.
*/
public void setNationalNumber(String nationalNumber) {
this.nationalNumber = nationalNumber;
}
/**
* Sets new nationality.
*
* #param nationality New value of nationality.
*/
public void setNationality(String nationality) {
this.nationality = nationality;
}
/**
* Sets new municipality.
*
* #param municipality New value of municipality.
*/
public void setMunicipality(Municipality municipality) {
this.municipality = municipality;
}
/**
* Gets phone.
*
* #return Value of phone.
*/
public String getPhone() {
return phone;
}
/**
* Sets new gender.
*
* #param gender New value of gender.
*/
public void setGender(char gender) {
this.gender = gender;
}
/**
* Gets contactNumber.
*
* #return Value of contactNumber.
*/
public String getContactNumber() {
return contactNumber;
}
/**
* Gets lastName.
*
* #return Value of lastName.
*/
public String getLastName() {
return lastName;
}
/**
* Sets new address.
*
* #param address New value of address.
*/
public void setAddress(String address) {
this.address = address;
}
/**
* Sets new firstName.
*
* #param firstName New value of firstName.
*/
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* Sets new birthPlace.
*
* #param birthPlace New value of birthPlace.
*/
public void setBirthPlace(Municipality birthPlace) {
this.birthPlace = birthPlace;
}
/**
* Gets nationality.
*
* #return Value of nationality.
*/
public String getNationality() {
return nationality;
}
/**
* Gets contactName.
*
* #return Value of contactName.
*/
public String getContactName() {
return contactName;
}
/**
* Gets birthDate.
*
* #return Value of birthDate.
*/
public Date getBirthDate() {
return birthDate;
}
/**
* Sets new contactName.
*
* #param contactName New value of contactName.
*/
public void setContactName(String contactName) {
this.contactName = contactName;
}
/**
* Sets new phone.
*
* #param phone New value of phone.
*/
public void setPhone(String phone) {
this.phone = phone;
}
/**
* Sets new contactNumber.
*
* #param contactNumber New value of contactNumber.
*/
public void setContactNumber(String contactNumber) {
this.contactNumber = contactNumber;
}
/**
* Sets new birthDate.
*
* #param birthDate New value of birthDate.
*/
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
/**
* Gets vaccinations.
*
* #return Value of vaccinations.
*/
public List<Vaccination> getVaccinations() {
return vaccinations;
}
/**
* Gets allergies.
*
* #return Value(Set) of allergies.
*/
public List<Allergy> getAllergies() {
return allergies;
}
/**
* Gets diseases.
*
* #return Value(List) of diseases.
*/
public List<Disease> getDiseases() {
return diseases;
}
/**
* Gets medications.
*
* #return Value(List) of medications.
*/
public List<Medication> getMedications() {
return medications;
}
/**
* Gets bloodgroup.
*
* #return Value of bloodgroup.
*/
public BloodType getBloodType() {
return bloodType;
}
/**
* Sets new bloodgroup.
*
* #param bloodType New value of bloodgroup.
*/
public void setBloodType(BloodType bloodType) {
this.bloodType = bloodType;
}
/**
* Gets HealthInsurance.
*
* #return Value of HealthInsureance.
*/
public HealthInsurance getHealthInsurance() {
return healthInsurance;
}
/**
* Sets new HealthInsurance.
*
* #param healthInsurance New value of HealthInsurance.
*/
public void setHealthInsurance(HealthInsurance healthInsurance) {
this.healthInsurance = healthInsurance;
}
/**
* Gets email.
*
* #return Value of email.
*/
public String getEmail() {
return email;
}
/**
* Sets new lastWill.
*
* #param lastWill New value of lastWill.
*/
public void setLastWill(boolean lastWill) {
this.lastWill = lastWill;
}
/**
* Sets new juridical.
*
* #param juridical New value of juridical.
*/
public void setJuridical(Juridical juridical) {
this.juridical = juridical;
}
/**
* Sets new allergies.
*
* #param allergies New value of allergies.
*/
public void setAllergies(List<Allergy> allergies) {
this.allergies = allergies;
}
/**
* Sets new diseases.
*
* #param diseases New value of diseases.
*/
public void setDiseases(List<Disease> diseases) {
this.diseases = diseases;
}
/**
* Gets lastWill.
*
* #return Value of lastWill.
*/
public boolean isLastWill() {
return lastWill;
}
/**
* Gets juridical.
*
* #return Value of juridical.
*/
public Juridical getJuridical() {
return juridical;
}
/**
* Sets new medications.
*
* #param medications New value of medications.
*/
public void setMedications(List<Medication> medications) {
this.medications = medications;
}
/**
* Sets new email.
*
* #param email New value of email.
*/
public void setEmail(String email) {
this.email = email;
}
/**
* Sets new vaccinations.
*
* #param vaccinations New value of vaccinations.
*/
public void setVaccinations(List<Vaccination> vaccinations) {
this.vaccinations = vaccinations;
}
}
Allergy.java
package medicapp.models.impl;
import javax.persistence.*;
import java.util.List;
#Entity
#Table(name="allergy")
public class Allergy {
#Id
#Column(name="Id")
#GeneratedValue
private int id;
#Column(name = "Description")
private String description;
#ManyToMany(mappedBy = "allergies")
private List<Patient> patients;
/**
* Default Constructor without parameters, this is required for using Hibernate
*/
public Allergy(){
}
/**
*
* #param description
*/
public Allergy(String description){
this.description = description;
}
/**
* Sets new id.
*
* #param id New value of id.
*/
public void setId(int id) {
this.id = id;
}
/**
* Sets new description.
*
* #param description New value of description.
*/
public void setDescription(String description) {
this.description = description;
}
/**
* Gets description.
*
* #return Value of description.
*/
public String getDescription() {
return description;
}
/**
* Gets id.
*
* #return Value of id.
*/
public int getId() {
return id;
}
}
Now, if I would call the getAllergies from a Patient object, it will generate this SQL code:
select
allergies0_.PatientId as PatientI1_11_0_,
allergies0_.AllergyId as AllergyI2_1_0_,
allergy1_.Id as Id1_0_1_,
allergy1_.Description as Descript2_0_1_
from
allergypatient allergies0_
inner join
allergy allergy1_
on allergies0_.AllergyId=allergy1_.Id
where
allergies0_.PatientId=?
This would mean I get these results:
2 3 3 Lactose
2 5 5 Animals
2 5 5 Animals
2 19 19 Pennicilline
Now if I print out the Description of the Allergy instances, it will always give me Hay, since that is the Allergy with id 2.
I need to have the second column to be the column that gets used to get the Allergies. Is there a way for me to change this?
Kind regards
You can specify join collumns with jpa/ which hibernate implements.Here is an example
#ManyToMany
#JoinTable(
name="EMP_PROJ",
joinColumns={#JoinColumn(name="EMP_ID", referencedColumnName="ID")},
inverseJoinColumns={#JoinColumn(name="PROJ_ID", referencedColumnName="ID")})
private List projects;

Junit testing for exceptions in a constructor?

In the following test I am trying to test if an exception has been thrown by the constructor when it is passed illegal arguments when trying to create the object, I have added validation in the setters of each instance variable that when they are passed invalid data they throw an exception.
// test for invalid const
#Test(expected = IllegalArgumentException.class)
public void testInvalidBookStringStringStringInt() {
// create a new book
Book b = new Book(invalidISBN, invalidAuthor, invalidTitle,
invalidRating1);
}
The test is currently failing at the minute, what am i doing wrong?
Book class:
package practice;
/**
* Class that creates a Book
*
* #author Ross Young
*
*/
public class Book {
// declaring instance variables
/**
* Book's ISBN
*/
private String ISBN;
/**
* Book's Author
*/
private String author;
/**
* Book's Title
*/
private String title;
/**
* Book's rating
*/
private int rating;
/**
* Default constructor
*/
public Book() {
}
/**
* Constructor with Args
*
* #param ISBN
* #param author
* #param title
* #param rating
*/
public Book(String ISBN, String author, String title, int rating) {
this.ISBN = ISBN;
this.author = author;
this.title = title;
this.rating = rating;
}
/**
* Gets ISBN
*
* #return ISBN
*/
public String getISBN() {
return ISBN;
}
/**
* Sets ISBN
*
* #param iSBN
*/
public void setISBN(String iSBN) {
if((iSBN.length()!=9)||(iSBN.length()!=12)){
throw new IllegalArgumentException("Invalid ISBN length");
}else{
this.ISBN=iSBN;
}
}
/**
* Gets Author
*
* #return author
*/
public String getAuthor() {
return author;
}
/**
* Sets author
*
* #param author
*/
public void setAuthor(String author) {
if ((author.length() < 0) || (author.length() > 20)) {
throw new IllegalArgumentException("Invalid author Length");
} else {
this.author = author;
}
}
/**
* gets title
*
* #return title
*/
public String getTitle() {
return title;
}
/**
* Sets title
*
* #param title
*/
public void setTitle(String title) {
if ((title.length() < 0) || (title.length() > 20)) {
throw new IllegalArgumentException("Invalid title Length");
} else {
this.title = title;
}
}
/**
* Gets rating
*
* #return rating
*/
public int getRating() {
return rating;
}
/**
* Sets rating
*
* #param rating
*/
public void setRating(int rating) {
if((rating>5)|| (rating<1)){
throw new IllegalArgumentException("Rating invalid");
}
this.rating = rating;
}
}
Your constructor doesn't perform any of the checks that your setters check, so it won't ever throw any exceptions. Setters aren't called when you directly assign an instance variable; they're only called explicitly.
Either have your constructor call your setters, or implement the validation in your constructor.
You need to call the setX methods from your constructor. Also change setISBN to :
if((iSBN.length()!=9) && (iSBN.length()!=12)) {
throw new IllegalArgumentException("Invalid ISBN length");
Your constructor is setting the private variables and not using the public setters that contain the validation.

Categories

Resources