How to save list of nested two separate objects - json

How to write model class and establish relation between classes. To save and update the below the JSON using spring boot.
inputJSON
{
"modelName": "",
"modelDescription": "",
"recordStatus": true,
"details": [
{
"tMemberDetail": {
"param1": "",
"pn": {
"param1": "",
"param2": ""
},
"an": {
"param1": "",
"param2": ""
},
"p": {
"h": {
"param1": "",
"param2": ""
},
"v": {
"param1": "",
"param2": ""
},
"r": {
"param1": "",
"param2": ""
}
},
"t": {
"param1": ""
}
},
"mattributes": {
"param1": "",
"SP": {
"param1": "",
"param2": ""
},
"EP": {
"param1": "",
"param2": ""
},
"F": {
"Required": false,
"FT": "",
"G": {
"param1": ""
},
"FP": {
"param1": "",
"param2": ""
},
"Pmr": {
"Required": false,
"Details": {
"param1": "",
"param2": ""
}
},
"Pnt": {
"Required": false,
"Details": {
"param1": "",
"param2": ""
}
},
"ASS": {
"Required": false,
"Details": {
"param1": ""
}
},
"NPA": {
"Required": false,
"Details": {
"param1": "",
"param2": ""
}
}
},
"Start": {
"param1": "",
"Loads": {
"param1": ""
}
},
"End": {
"param1": "",
"Loads": {
"param1": ""
}
}
}
}
]
}
I have tried to achieve by writing model class like below
#Setter
#Getter
#ToString
#Entity
#NoArgsConstructor
public class Model extends BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long modelId;
private String modelName;
private String modelDescription;
private RecordStatus recordStatus=RecordStatus.ACTIVE;
}
#Setter
#Getter
#Entity
#NoArgsConstructor
public class TModel extends Model implements Serializable{
private static final long serialVersionUID = 7331603514610649855L;
#OneToMany(cascade = CascadeType.ALL , orphanRemoval = true)
private List<TMember > tMembers ;
}
#Setter
#Getter
#ToString
#Entity
#NoArgsConstructor
public class TMember implements Serializable{
private static final long serialVersionUID = 7331603514610649855L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long tMemberId;
#OneToOne(cascade = CascadeType.ALL , orphanRemoval = true)
private TMemberDetail tMemberDetail;
#OneToOne(cascade = CascadeType.ALL , orphanRemoval = true)
private MemberAttribute memberAttributes;
}
The problem I am facing here is that every time I update call child objects, auto incremental id's are incremented by 1.
If I call get service from another application I get only
modelName, modelDescription, recordStatus but not the entire data.

Related

Managing circular dependency in JSON response

How do I handle the dependency between the two entities? I want to be able to get the games for a player and also players for a game. I am currently trying to do it with #JsonIdentityInfo but the result is not satisfying.
#Entity
#Table(name = "player", uniqueConstraints = { #UniqueConstraint(columnNames = "id") })
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Player.class)
public class Player{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "games_admins", joinColumns = { #JoinColumn(name = "player_id") }, inverseJoinColumns = {
#JoinColumn(name = "game_id") })
private Set<Game> games;
#Entity
#Table(name = "game", uniqueConstraints = { #UniqueConstraint(columnNames = "id") })
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Game.class)
public class Game{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
#ManyToMany(mappedBy = "games")
private Set<Player> players;
So when I send a GET request to get all of the players I want to receive something like this
[
{
"id": 1,
"name": "Player1",
"games": [
{
"id": 1,
"name": "game1",
"players": [1, 2, 3]
},
{
"id": 2,
"name": "game2",
"players": [1, 3]
},
{
"id": 3,
"name": "game3",
"players": [1, 2]
}
]
},
{
"id": 2,
"name": "Player2",
"games": [
{
"id": 1,
"name": "game1",
"players": [1, 2, 3]
},
{
"id": 3,
"name": "game3",
"players": [1, 2]
}
]
},
{
"id": 3,
"name": "Player3",
"games": [
{
"id": 1,
"name": "game1",
"players": [1, 2, 3]
},
{
"id": 2,
"name": "game2",
"players": [1, 3]
}
]
}
]
So when we reach the "player" again we don't list the games but their ids to avoid the recursion. Same should apply for games.
But what I get is this:
[
{
"id": 1,
"name": "Player1",
"games": [
{
"id": 2,
"name": "game2",
"players": [
1,
{
"id": 3,
"name": "Player3",
"games": [
2,
{
"id": 1,
"name": "game1",
"players": [
{
"id": 2,
"name": "Player2",
"games": [
1,
{
"id": 3,
"name": "game3",
"players": [2, 1]
}
]
},
1,
3
]
}
]
}
]
},
1,
3
]
},
2,
3
]

JsonBackReference not working as expected

I have the next two clases...
Class A
#Entity
#Table(name="ClassA")
public class ClassA
{
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "Id", unique = true, nullable = false)
private Long id;
#Column(name = "Name", nullable = false, length = 50)
private String name;
#JsonManagedReference
#OneToMany(mappedBy="classA")
private List<ClassB> classBList;
}
Class B
#Entity
#Table(name = "ClassB")
public class ClassB
{
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "Id", unique = true, nullable = false)
private Long id;
#Column(name = "Name", nullable = false, length = 50)
private String name;
#JsonBackReference
#ManyToOne
#JoinColumn(name = "ClassAId", nullable = false)
private ClassA classA;
}
When i do a get of all ClassA records from database using REST the result is working like charm:
GET http://localhost:8080/REST/ClassA
[
{
"id": 1,
"name": "VVVV I",
"classB": [
{
"id": 1,
"name": "SSSS I"
},
{
"id": 2,
"name": "QQQQ II",
}
]
},
{
"id": 2,
"name": "RRRR II",
"classB": []
},
{
"id": 3,
"name": "FFFFF III",
"classB": []
},
{
"id": 4,
"name": "QWERR",
"classB": [
{
"id": 3,
"name": "GGGG III",
},
{
"id": 4,
"name": "HHHH IV",
},
{
"id": 5,
"name": "JJJJ V",
}
]
},
{
"id": 5,
"name": "TRRR",
"classB": []
}
]
The problem is when i want to get the list of ClassB, the ClassA is not returning at all...
GET http://localhost:8080/REST/ClassB
[
{
"id": 1,
"name": "SSSS I"
},
{
"id": 2,
"name": "QQQQ II"
},
{
"id": 3,
"name": "GGGG III"
},
{
"id": 4,
"name": "HHHH IV"
},
{
"id": 5,
"name": "JJJJ V"
}
]
I need ClassA (without classB inside of it) be listed when getting list of ClassB
How can i achieve that?
Best regards

How to process sabre InstaFlight API JSON response

I connected to saber InstaFlight API and got a result in JSON. The output string is too long and I can get their values. But my way is taking lots of memory storage. I want a way that takes less memory storage and a dynamic way in VB.NET.
The code below is working fine with no error:
response2 = DirectCast(postReq.GetResponse(), HttpWebResponse)
reader2 = New StreamReader(response2.GetResponseStream())
postReq.ContentType = "application/json; charset=utf-8"
Dim ser1 As JObject = JObject.Parse(reader2.ReadToEnd())
I can get the values like this, with no error:
ElapseTime1 = ser1("PricedItineraries")(0)("AirItinerary")("OriginDestinationOptions")("OriginDestinationOption")(0)("ElapsedTime").Value(Of String)()
However, it gets to a point that you need hundreds of variables and this is not the right way.
An example of the output JSON:
{ "PricedItineraries": [ { "AirItinerary": { "OriginDestinationOptions": { "OriginDestinationOption": [ { "FlightSegment": [ { "DepartureAirport": { "LocationCode": "JFK" }, "ArrivalAirport": { "LocationCode": "LAS" }, "MarketingAirline": { "Code": "AS" }, "ArrivalTimeZone": { "GMTOffset": -7 }, "TPA_Extensions": { "eTicket": { "Ind": true } }, "StopQuantity": 0, "ElapsedTime": 344, "ResBookDesigCode": "R", "MarriageGrp": "O", "Equipment": { "AirEquipType": 320 }, "DepartureDateTime": "2017-07-07T09:30:00", "ArrivalDateTime": "2017-07-07T12:14:00", "FlightNumber": 1251, "OnTimePerformance": { "Percentage": 70 }, "OperatingAirline": { "CompanyShortName": "VIRGIN AMERICA", "FlightNumber": 251, "Code": "VX" }, "DepartureTimeZone": { "GMTOffset": -4 } }, { "DepartureAirport": { "LocationCode": "LAS" }, "ArrivalAirport": { "LocationCode": "LAX" }, "MarketingAirline": { "Code": "AS" }, "ArrivalTimeZone": { "GMTOffset": -7 }, "TPA_Extensions": { "eTicket": { "Ind": true } }, "StopQuantity": 0, "ElapsedTime": 85, "ResBookDesigCode": "R", "MarriageGrp": "O", "Equipment": { "AirEquipType": 320 }, "DepartureDateTime": "2017-07-07T14:45:00", "ArrivalDateTime": "2017-07-07T16:10:00", "FlightNumber": 1475, "OnTimePerformance": { "Percentage": 36 }, "OperatingAirline": { "CompanyShortName": "VIRGIN AMERICA", "FlightNumber": 475, "Code": "VX" }, "DepartureTimeZone": { "GMTOffset": -7 } } ], "ElapsedTime": 580 }, { "FlightSegment": [ { "DepartureAirport": { "LocationCode": "LAX" }, "ArrivalAirport": { "LocationCode": "LAS" }, "MarketingAirline": { "Code": "AS" }, "ArrivalTimeZone": { "GMTOffset": -7 }, "TPA_Extensions": { "eTicket": { "Ind": true } }, "StopQuantity": 0, "ElapsedTime": 71, "ResBookDesigCode": "R", "MarriageGrp": "O", "Equipment": { "AirEquipType": 320 }, "DepartureDateTime": "2017-07-08T17:00:00", "ArrivalDateTime": "2017-07-08T18:11:00", "FlightNumber": 1480, "OnTimePerformance": { "Percentage": 55 }, "OperatingAirline": { "CompanyShortName": "VIRGIN AMERICA", "FlightNumber": 480, "Code": "VX" }, "DepartureTimeZone": { "GMTOffset": -7 } }, { "DepartureAirport": { "LocationCode": "LAS" }, "ArrivalAirport": { "LocationCode": "JFK" }, "MarketingAirline": { "Code": "AS" }, "ArrivalTimeZone": { "GMTOffset": -4 }, "TPA_Extensions": { "eTicket": { "Ind": true } }, "StopQuantity": 0,
I think you need to create a model for this result. According to this JSON, you have to create a class model.
If you have this JSON:
{
"dailyDealId": "432",
"discountPercentage": "0",
"product": {
"productId": "10",
"brandId": "10",
"departmentId": "3",
"name": "Baby Girl Velour Tunic & Snowflake Legging Set",
"description": "The pretty set",
"url": "http://whatever.whatever.com/files/whatever.tif"
}
You need this model:
public class Product
{
public string productId { get; set; }
public string brandId { get; set; }
public string departmentId { get; set; }
public string name { get; set; }
public string description { get; set; }
public string url { get; set; }
}
public class Data
{
public string dailyDealId { get; set; }
public string discountPercentage { get; set; }
public Product product { get; set; }
}

Avoid circular self references in hibernate entity

I have a Hibernate entity with self references
#Entity
#Table(name = "category")
#NamedQuery(name = "Category.findAll", query = "SELECT c FROM Category c")
public class Category implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(nullable = false, length = 255)
private String name;
#Column(length = 255)
private String description;
#Column(nullable = false, length = 25, columnDefinition = "enum('Category','SubCategory','Indicator')")
private String type;
#ManyToMany
#JoinTable(name = "CategoryHierarchy", joinColumns = #JoinColumn(name = "parentId", referencedColumnName = "id"), inverseJoinColumns = #JoinColumn(name = "childId", referencedColumnName = "id"))
private List<Category> childs;
// getters and setters
}
So, obviously I was facing infinite recursion while deserializing the JSON when I was getting all the entities. So I added
#JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "#id")
above the class name.
But now, the JSON only contains ids or numbers like
{
"success": true,
"messages": [
{
"#id": 1,
"id": 5,
"name": "TestParentCategory ",
"description": "This is test Parent category",
"type": "Category",
"status": "New",
"childs": [
{
"#id": 2,
"id": 6,
"name": "TestChildCategory",
"description": "This is test child category",
"editTime": "2016-03-23T11:40:19",
"editedBy": null,
"createTime": "2016-03-23T11:40:19",
"createdBy": 10,
"type": "SubCategory",
"status": "New",
"childs": [
{
"#id": 3,
"id": 8,
"name": "TestChildCategory",
"description": "This is test child category",
"editTime": "2016-03-23T11:40:20",
"editedBy": null,
"createTime": "2016-03-23T11:40:20",
"createdBy": 10,
"type": "Indicator",
"status": "New",
"childs": [],
"parents": [
2,
{
"#id": 4,
"id": 7,
"name": "TestChildCategory",
"description": "This is test child category",
"editTime": "2016-03-23T11:40:19",
"editedBy": null,
"createTime": "2016-03-23T11:40:19",
"createdBy": 10,
"type": "SubCategory",
"status": "New",
"childs": [
3,
{
"#id": 5,
"id": 9,
"name": "TestChildCategory",
"description": "This is test child category",
"editTime": "2016-03-23T11:40:20",
"editedBy": null,
"createTime": "2016-03-23T11:40:20",
"createdBy": 10,
"type": "Indicator",
"status": "New",
"childs": [],
"parents": [
2,
4
],
"opinions": [],
"timestamp": "2016-03-23T11:40:20",
"edited": "2016-03-23T11:40:20"
}
]
}
],
},
]
}
]
},
2,
4,
3,
5
]
}
I dont want numbers in the array (2, 4, 3, 5) but I want actual objects. How can I do that?
UPDATE
I also went through the question
so is it the only way to do it?

Deserializing JSON using JSon.NET with dynamic data

I'm trying to deserialize some JSON data into objects for an application. Up until now it's been fine because the properties on the JSON data was static (key with a value). Now I've got a result where the key is a dynamic piece of data.
Here's an example JSON url:
http://en.wikipedia.org/w/api.php?action=query&format=json&pageids=6695&prop=info
The resulting JSON for this is:
{ "query" : { "pages" : { "6695" : { "counter" : "",
"lastrevid" : 468683764,
"length" : 8899,
"ns" : 0,
"pageid" : 6695,
"title" : "Citadel",
"touched" : "2012-01-03T19:16:16Z"
} } } }
Okay, that's great except I can't deserialize the "pages" data into an object. If I were to define a class for the pages it would have to look like this:
public class 6695
{
public string counter { get; set; }
public int lastrevid { get; set; }
public int length { get; set; }
public int ns { get; set; }
public int pageid { get; set; }
public string title { get; set; }
public string touched { get; set; }
}
In order to deserialze the contents (using JsonConvert.Deserialize(jsondata)) and we all know we can't have a class called 6695. Not only that, the name of the class would have to be different (for example pageid=7145 would have to be the 7145 class).
I can seem to pluck some values out if I use something like JObject.Parse(content) and then access items as JArrays but it's pretty ugly and I'm still stuck on trying to get out the data from the pages array.
Looking for someone to help with this. I don't think it's uncommon, it's just not JSON data I've come across before and not sure how to handle it.
Thanks!
PS forgot to mention this is on Windows Phone 7 so "dynamic" isn't available!
The simplest method. In this particular case would probably be to go dynamic.
dynamic data = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
var lastRevId = data.query.pages["6695"].lastrevid;
You can reference any element by it's [] name so you can do something like data["query"]["pages"]["6695"]["lastrevid"]. This will get by all those little objects where the name isn't valid in c#.
Here is how you do using https://github.com/facebook-csharp-sdk/simple-json ( https://nuget.org/packages/SimpleJson ).
var text = "{\"query\":{\"pages\":{\"6695\":{\"pageid\":6695,\"ns\":0,\"title\":\"Citadel\",\"touched\":\"2012-01-03T19:16:16Z\",\"lastrevid\":468683764,\"counter\":\"\",\"length\":8899}}}}";
(Using dynamic)
dynamic json = SimpleJson.DeserializeObject(text);
string title = json.query.pages["6695"].title;
foreach (KeyValuePair<string, dynamic> page in json.query.pages)
{
var id = page.Key;
var pageId = page.Value.pageid;
var ns = page.Value.ns;
}
(Using strongly typed classes)
class result
{
public query query { get; set; }
}
class query
{
public IDictionary<string, page> pages { get; set; }
}
class page
{
public long pageid { get; set; }
public string title { get; set; }
}
var result = SimpleJson.DeserializeObject<result>(text);
[Update]
on windows phone where dynamic is not supported and you don't want to use strongly typed classes.
var json = (IDictionary<string, object>)SimpleJson.DeserializeObject(text);
var query = (IDictionary<string, object>)json["query"];
var pages = (IDictionary<string, object>)query["pages"];
var pageKeys = pages.Keys;
var page = (IDictionary<string, object>)pages["6695"];
var title = (string)page["title"];
I hope the below example will help.
I always design a model that match the json. It is much better to work with the object when it is your own model design.
It is very easy to generate the c# model from the json. I use this website to generate the model: http://json2csharp.com
A complete example is:
C# Code:
var targetsObject = Newtonsoft.Json.JsonConvert.DeserializeObject<YourModel>(jsonString);
JSON:
{
"investors": [
{
"name": "06",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": "5.5"
},
{
"name": "VA IRRRL",
"value": "6.0"
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "07",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": "7.0"
},
{
"name": "VA",
"value": "5.5"
},
{
"name": "VA IRRRL",
"value": ""
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "08",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": "7.0"
},
{
"name": "VA",
"value": "5.5"
},
{
"name": "VA IRRRL",
"value": ""
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "09",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": "5.5"
},
{
"name": "VA IRRRL",
"value": ""
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "10",
"programs": [
{
"name": "Conventional",
"value": ""
},
{
"name": "FHA - Standard",
"value": ""
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": ""
},
{
"name": "VA IRRRL",
"value": ""
},
{
"name": "Non-Prime",
"value": "2.0"
}
]
},
{
"name": "11",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": "6.0"
},
{
"name": "VA IRRRL",
"value": "6.0"
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "12",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": "5.5"
},
{
"name": "VA IRRRL",
"value": "6.0"
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "13",
"programs": [
{
"name": "Conventional",
"value": ""
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": ""
},
{
"name": "VA IRRRL",
"value": ""
},
{
"name": "Non-Prime",
"value": "2.0"
}
]
}
]
}
Model:
public class Program
{
public string name { get; set; }
public string value { get; set; }
}
public class Investor
{
public string name { get; set; }
public List<Program> programs { get; set; }
}
public class RootObject
{
public List<Investor> investors { get; set; }
}
Using Json.net you can just do:
Dictionary<string,object> result = JsonConvert.DeserializeObject<Dictionary<string,object>>(json);
foreach(var item in result)
Console.WriteLine(item.Key + " " + item.Value);
How about a simple search and replace in the JSON string ? While it might not be the most elegant solution, it would possibly be the most pragmatic one.
Maybe you could just use one reserved attribute to contain the object type, and then use the base type as shown in this article: Dynamic types with JSON.NET