I'm working on an application and I need to save and load data from an ObservableArrayList to an XML file. I've made a model class with Double and Integer Properties for the ObservableList:
package application.Model;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
#XmlRootElement
#XmlType(name = "Object", propOrder = {"diameter", "handeling", "aantal", "basisUren", "correctie", "toeslagUren", "totaalUren", "totaalMat", "totaal"})
public class Berekening {
private final SimpleIntegerProperty diameter;
private final SimpleIntegerProperty handeling;
private final SimpleIntegerProperty aantal;
private final SimpleDoubleProperty basisUren;
private final SimpleDoubleProperty correctie;
private final SimpleDoubleProperty toeslagUren;
private final SimpleDoubleProperty totaalUren;
private final SimpleDoubleProperty totaalMat;
private final SimpleDoubleProperty totaal;
public Berekening() {
this(null, null, null, null, null, null, null, null, null);
}
public Berekening(Integer diameter, Integer handeling, Integer aantal, Double basisUren, Double correctie, Double toeslagUren, Double totaalUren, Double totaalMat, Double totaal) {
this.diameter = new SimpleIntegerProperty(diameter);
this.handeling = new SimpleIntegerProperty(handeling);
this.aantal = new SimpleIntegerProperty(aantal);
this.basisUren = new SimpleDoubleProperty(basisUren);
this.correctie = new SimpleDoubleProperty(correctie);
this.toeslagUren = new SimpleDoubleProperty(toeslagUren);
this.totaalUren = new SimpleDoubleProperty(totaalUren);
this.totaalMat = new SimpleDoubleProperty(totaalMat);
this.totaal = new SimpleDoubleProperty(totaal);
}
#XmlElement (name = "value1", required = false)
public Integer getDiameter() {
return diameter.get();
}
public void setDiameter(int diameter) {
this.diameter.set(diameter);
}
public IntegerProperty diameterProperty(){
return diameter;
}
#XmlElement (name = "value2", required = false)
public Integer getHandeling() {
return handeling.get();
}
public void setHandeling(int handeling) {
this.handeling.set(handeling);
}
public IntegerProperty handelingProperty(){
return handeling;
}
#XmlElement (name = "value3", required = false)
public Integer getAantal() {
return aantal.get();
}
public void setAantal(int aantal) {
this.aantal.set(aantal);
}
public IntegerProperty aantalProperty(){
return aantal;
}
#XmlElement (name = "value4", required = false)
public Double getBasisUren(){
return basisUren.get();
}
public void setBasisUren(double value) {
this.basisUren.set(value);
}
public DoubleProperty basisUrenProperty(){
return basisUren;
}
#XmlElement (name = "value5", required = false)
public Double getCorrectie(){
return correctie.get();
}
public void setCorrectie(double value) {
this.correctie.set(value);
}
public DoubleProperty correctieProperty(){
return correctie;
}
#XmlElement (name = "value6", required = false)
public Double getToeslagUren(){
return toeslagUren.get();
}
public void setToeslagUren(double value) {
this.toeslagUren.set(value);
}
public DoubleProperty toeslagUrenProperty(){
return toeslagUren;
}
#XmlElement (name = "value7", required = false)
public Double getTotaalUren(){
return totaalUren.get();
}
public void setTotaalUren(double value) {
this.totaalUren.set(value);
}
public DoubleProperty totaalUrenProperty(){
return totaalUren;
}
#XmlElement (name = "value8", required = false)
public Double getTotaalMat(){
return totaalMat.get();
}
public void setTotaalMat(double value) {
this.totaalMat.set(value);
}
public DoubleProperty totaalMatProperty(){
return totaalMat;
}
#XmlElement (name = "value9", required = false)
public Double getTotaal(){
return totaal.get();
}
public void setTotaal(double value) {
this.totaal.set(value);
}
public DoubleProperty totaalProperty(){
return totaal;
}
}
This is the list class:
package application.Model;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
public class BerekeningList {
#XmlElement(name = "berekening")
List<Berekening> berekeningen = new ArrayList<>();
public List<Berekening> getBerekeningen() {
return berekeningen;
}
}
And the ListWrapper:
package application.Model;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import application.MainApp;
import application.Util.BerekeningListAdapter;
import javafx.collections.ObservableList;
#XmlRootElement (name = "Berekeningen")
public class BerekeningListWrapper{
private ObservableList<Berekening> berekening;
#XmlJavaTypeAdapter(BerekeningListAdapter.class)
public ObservableList<Berekening> getBerekeningen(){
return berekening;
}
public void setBerekenings(ObservableList<Berekening> berekenings) {
this.berekening = berekenings;
}
}
I use this method to Save the data to a file:
public void saveBerekeningDataToFile(File file) {
try {
JAXBContext context = JAXBContext
.newInstance(BerekeningListWrapper.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
BerekeningListWrapper wrapper = new BerekeningListWrapper();
wrapper.setBerekenings(berekeningData);
m.marshal(wrapper, file);
setBerekeningFilePath(file);
} catch (Exception e) {
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("Could not save data");
alert.setContentText("Could not save data to file:\n" + file.getPath());
alert.showAndWait();
}
}
And the resulting xml file (the saving seems to work fine):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Berekeningen>
<berekeningen>
<berekening value1="15" value2="5" value3="5" value4="1.25" value5="5.0" value6="6.25" value7="270.0" value8="30.0" value9="300.0"/>
</berekeningen>
The issue is loading the data back into my application, i'm using this method:
public void loadBerekeningDataFromFile(File file){
try {
JAXBContext context = JAXBContext
.newInstance(BerekeningListWrapper.class);
Unmarshaller um = context.createUnmarshaller();
BerekeningListWrapper wrapper = (BerekeningListWrapper)um.unmarshal(file);
berekeningData.clear();
berekeningData.addAll(wrapper.getBerekeningen());
setBerekeningFilePath(file);
} catch (Exception e){
e.printStackTrace();
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("Could not load data");
alert.setContentText("Could not load data from file:\n" + file.getPath());
alert.showAndWait();
}
}
Resulting in a stack trace starting with:
javax.xml.bind.UnmarshalException: Unable to create an instance of
application.Model.Berekening
etc
Caused by: java.lang.NullPointerException
at application.Model.Berekening.<init>(Berekening.java:32)
at application.Model.Berekening.<init>(Berekening.java:28)
... 84 more
So the unmarshalexception is caused by a NullPointerException in my model class at the lines:
this.diameter = new SimpleIntegerProperty(diameter);
and
this(null, null, null, null, null, null, null, null, null);
I don't know how I can resolve this issue, I've tried out many different tutorials and answers on StackOverflow, but nothing I found neems to work.
Any help is much appreciated!
You can't initialize a SimpleIntegerProperty with null. The constructor you are calling takes an int, so there is an implicit call ("unboxing") to diameter.intValue() when you call new SimpleIntegerProperty(diameter). Obviously, if diameter is null, this results in a NullPointerException.
Make the default values for the numeric types non-null:
public Berekening() {
this(0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
}
for example.
If you really need to support null values (and this is a less-preferred option, imho) use ObjectProperty instead of IntegerProperty and DoubleProperty:
public class Berekening {
private final ObjectProperty<Integer> diameter;
private final ObjectProperty<Integer> handeling;
private final ObjectProperty<Integer> aantal;
private final ObjectProperty<Double> basisUren;
private final ObjectProperty<Double> correctie;
private final ObjectProperty<Double> toeslagUren;
private final ObjectProperty<Double> totaalUren;
private final ObjectProperty<Double> totaalMat;
private final ObjectProperty<Double> totaal;
public Berekening() {
this(null, null, null, null, null, null, null, null, null);
}
public Berekening(Integer diameter, Integer handeling, Integer aantal, Double basisUren, Double correctie, Double toeslagUren, Double totaalUren, Double totaalMat, Double totaal) {
this.diameter = new SimpleObjectProperty<>(diameter);
this.handeling = new SimpleObjectProperty<>(handeling);
this.aantal = new SimpleObjectProperty<>(aantal);
this.basisUren = new SimpleObjectProperty<>(basisUren);
this.correctie = new SimpleObjectProperty<>(correctie);
this.toeslagUren = new SimpleObjectProperty<>(toeslagUren);
this.totaalUren = new SimpleObjectProperty<>(totaalUren);
this.totaalMat = new SimpleObjectProperty<>(totaalMat);
this.totaal = new SimpleObjectProperty<>(totaal);
}
// ...
}
Related
This is the generic method through which i am accepting list of
objects and downcasting to a specific object
public Response generate(List<?> list){
List<ClassA> List1 = new ArrayList<ClassA>();
List<ClassB> List2 = new ArrayList<ClassB>();
List<ClassC> List3 = new ArrayList<ClassC>();
if(list instanceof List<?>){
List1=(List<ClassA>) list;//in this line i am getting error
addDataToExcel(List1);
}
else if(list instanceof List<?>){
List2=(List<ClassB>) list;
addDataToExcel(List1);
}
else if(list instanceof List<?>){
List3=(List<ClassC>) list;
addDataToExcel(List1);
}
This is classA
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
#Entity
#Table(name="ClassA")
public class ClassA {
#Id
#Column(name="rollNo")
private int rollNo;
#Column(name="name")
private String name;
#Column(name="english")
private double english;
#Column(name="maths")
private double maths;
#Column(name="science")
private double science;
#Column(name="totalMarks")
private double totalMarks;
#Column(name="percentage")
private double percentage;
#Column(name="status")
private boolean status;
#Lob
#Column(name="file", columnDefinition="BLOB")
private byte[] file;
public ClassA() {
// TODO Auto-generated constructor stub
}
public ClassA(int rollNo, String name, double english, double maths, double science, double totalMarks,
double percentage, boolean status, byte[] file) {
super();
this.rollNo = rollNo;
this.name = name;
this.english = english;
this.maths = maths;
this.science = science;
this.totalMarks = totalMarks;
this.percentage = percentage;
this.status = status;
this.file = file;
}
public int getRollNo() {
return rollNo;
}
public void setRollNo(int rollNo) {
this.rollNo = rollNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getEnglish() {
return english;
}
public void setEnglish(double english) {
this.english = english;
}
public double getMaths() {
return maths;
}
public void setMaths(double maths) {
this.maths = maths;
}
public double getScience() {
return science;
}
public void setScience(double science) {
this.science = science;
}
public double getTotalMarks() {
return totalMarks;
}
public void setTotalMarks(double totalMarks) {
this.totalMarks = totalMarks;
}
public double getPercentage() {
return percentage;
}
public void setPercentage(double percentage) {
this.percentage = percentage;
}
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
public byte[] getFile() {
return file;
}
public void setFile(byte[] file) {
this.file = file;
}
}
This is the method which accepts List and generate excel
public void add(List<ClassA> classA) {
System.out.println("entering add");
String excelFilePath = "D:/eclipse_neon/StudentInfo.xlsx";
try {
FileInputStream inputStream = new FileInputStream(new File(excelFilePath));
Workbook workbook = WorkbookFactory.create(inputStream);
Sheet sheet = workbook.getSheetAt(0);
int rowNum = 1;
int a=2;
for(ClassA info: classA){
System.out.println("netering loop");
Row row = sheet.getRow(rowNum++);
row.createCell(2).setCellValue(info.getEnglish());
row.createCell(3).setCellValue(info.getMaths());
row.createCell(4).setCellValue(info.getScience());
row.createCell(5).setCellFormula("SUM(C"+a+","+"D"+a+","+"E"+a+")");
row.createCell(6).setCellFormula("("+"F"+a+"*"+"100"+")"+"/"+"300");
row.createCell(7).setCellValue(info.isStatus());
a++;
}
System.out.println("after for loop");
inputStream.close();
FileOutputStream outputStream = new FileOutputStream("D:/eclipse_neon/StudentInfo.xlsx");
workbook.write(outputStream);
workbook.close();
outputStream.close();
} catch (IOException | EncryptedDocumentException
| InvalidFormatException ex) {
ex.printStackTrace();
}
}
I am not able to downcast to my specific List of class from generic list soo any suggestions are welcomed Thankyou
That's probably because you're sending a list as parameter containing a List and class A is not related to LinkedHashMap (not a subclass for example) and therefore it cannot cast. If you can provide more details what is class A and what is the list you're sending as arguments to your method.
Check https://www.baeldung.com/java-type-casting
One of my api response is as below -
{
"statusCode": 422,
"error": "Unprocessable Entity",
"message": "Bad data received",
"err_data": {
"email": {
"location": "body",
"param": "email",
"value": false,
"msg": "Please provide valid e-mail address"
}
}
}
So, in below response.asString() represents above response body.
ApiResponse response = new Gson().fromJson(response.asString(), ApiResponse.class);
ApiResponse.class is my model which is as below:
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({ "statusCode", "message" })
public class ApiResponse implements Serializable {
private static final long serialVersionUID = 1L;
#JsonProperty("message")
private String message;
#JsonProperty("statusCode")
private int statusCode;
#JsonProperty("err_data")
private List<String> errData = new ArrayList<>();
#JsonProperty("email")
private List<String> email = new ArrayList<>();
#JsonProperty("msg")
private String msg;
/**
* No args constructor for use in serialization
*/
public ApiResponse() {
}
/**
* #param message
*/
public ApiResponse(int statusCode, String message, List<String> errData, List<String> email, String msg) {
this.message = message;
this.statusCode = statusCode;
this.errData = errData;
this.email = email;
this.msg = msg;
}
#JsonProperty("statusCode")
public int getStatusCode() {
return statusCode;
}
#JsonProperty("statusCode")
public void setStatusCode(int statusCode) {
this.statusCode = statusCode;
}
#JsonProperty("message")
public String getMessage() {
return message;
}
#JsonProperty("message")
public void setMessage(String message) {
this.message = message;
}
#JsonProperty("err_data")
public List<String> getErrData() {
return errData;
}
#JsonProperty("err_data")
public void setErrData(List<String> errData) {
this.errData = errData;
}
#JsonProperty("email")
public List<String> getEmail() {
return email;
}
#JsonProperty("email")
public void setEmail(List<String> email) {
this.email = email;
}
#JsonProperty("msg")
public String getMsg() {
return msg;
}
#JsonProperty("msg")
public void setMsg(String msg) {
this.msg = msg;
}
}
When I am trying to get msg under "email":{}, it is returning null.
ApiResponse apiResponse = new Gson().fromJson(response.asString(), ApiResponse.class);
// this prints correct value
System.out.println(apiResponse.getMessage());
// this prints correct value
System.out.println(apiResponse.getStatusCode());
// this prints empty string array => []
System.out.println(apiResponse.getErrData());
// this also prints empty string array => []
System.out.println(apiResponse.getEmail());
// this prints null
System.out.println(apiResponse.getMsg());
I am new to fasterxml.jackson lib and not sure what I am missing.
To get msg value, what changes I'll have to do in model class above. Thank you very much in advance.
This is where your code is incorrect :
#JsonProperty("err_data")
private List<String> errData = new ArrayList<>();
#JsonProperty("email")
private List<String> email = new ArrayList<>();
Both email and errData is not a List, they are a separate Object. Just like the ApiResponse.java, you need to create POJO for both objects. For example :
public class Email {
private String location;
private String param;
private String value;
private String msg;
// define getter and setter
}
and
public class ErrData {
private Email email;
// define getter and setter
}
Then use the new class as the object type.
#JsonProperty("err_data")
private ErrData errData;
// email is already inside ErrData, you don't need to define them here
Finally to access your msg :
errData.getEmail().getMsg();
Hope this is clear enough. Good luck!
PlayerService
this is srvice class of my boot app.
package io.anuj.springbootquickstart.topic;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class PlayerService {
#Autowired
private PlayerRespository playerRespository;
// private List<Topic> topics = new ArrayList<> (Arrays.asList(
// new Topic("Spring","Spring Framework","SpringFramework Description"),
// new Topic("Core","Core Framework","CoreFramework Description"),
// new Topic("JavaScript","JavaScript Framework","JavaScript Description")));
public List<Player> getAllPlayer(){
List<Player> player = new ArrayList();
playerRespository.findAll()
.forEach(player::add); //lambda expressions
return player;
}
public Player getPlayer(Long id){
//return topics.stream().filter(t -> t.getId().equals(id).findFirst().get());
return playerRespository.findOne(id);
}
public void addPlayer(Player player) {
playerRespository.save(player);
}
public void updatePlayer(Long id, Player player) {
playerRespository.save(player);
}
public void deletePlayer(Long id) {
//topics.removeIf(t -> t.getId().equals(id));
playerRespository.delete(id);
}
}
PLayerRepository
this is player repository of my app.
package io.anuj.springbootquickstart.topic;
import org.springframework.data.repository.CrudRepository;
public interface PlayerRespository extends CrudRepository <Player, Long>{
//crud repository-logic of any entity class
//getallTopic()
//gettopic(string id)
//update topic(topic t)
//deletetopic(string id)
}
PLayerController
this is player controller
package io.anuj.springbootquickstart.topic;
import java.io.FileReader;
import java.util.List;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#RestController
//wherever rest controller is written it will give json as output send back as a HTTP response
public class PlayerController {
#Autowired
private PlayerService playerService;
//get request by default
#RequestMapping("/player")
public List<Player> getallPlayer(){
return playerService.getAllPlayer();
}
//get request
#RequestMapping("/player/{id}")
public Player getPlayer(#PathVariable Long id){
return playerService.getPlayer(id);
}
//
#RequestMapping(method=RequestMethod.GET, value= "/getplayer")
public void addAllPlayer(){
Player player = new Player();
JSONParser parser = new JSONParser();
try {
Object ob = parser.parse(new FileReader("/home/bridgeit/Desktop/P.D-anuj/Json/newPlayerInfo.json"));
JSONObject object = (JSONObject) ob;
JSONArray data = (JSONArray) object.get("Playersinfo");
for (int i = 0; i < data.size(); i++)
{
JSONObject itemObj = (JSONObject) data.get(i);
Object nameObj = itemObj.get("player_name");
String playerName = (String) nameObj;
player.setPlayer_name(playerName);
Object imgObject = itemObj.get("player_img_url");
String playerPic = (String) imgObject;
player.setPlayer_img_url(playerPic);
Object roleObj = itemObj.get("player_role");
String roleName = (String) roleObj;
player.setPlayer_role(roleName);
Object battingStyleObj = itemObj.get("player_batting_style");
String battingStyleName = (String) battingStyleObj;
player.setPlayer_batting_style(battingStyleName);
Object bowlingObj = itemObj.get("player_bowling_style");
String bowlingName = (String) bowlingObj;
player.setPlayer_bowling_style(bowlingName);
Object nationalityObj = itemObj.get("player_nationality");
String nationalityName = (String) nationalityObj;
player.setPlayer_nationality(nationalityName);
Object dobObj = itemObj.get("player_dob");
String dobName = (String) dobObj;
player.setPlayer_dob(dobName);
Object teamIdObj = itemObj.get("team_id");
String teamIdName = (String) teamIdObj;
player.setTeam_id(teamIdName);
playerService.addPlayer(player);
}
} catch (Exception e) {
System.out.println(e);
}
}
/*#RequestMapping(method=RequestMethod.PUT, value= "/player/{id}")
public void updatePlayer(#RequestBody Player player,#PathVariable String id){
playerService.updatePlayer(id,player);
}
#RequestMapping(method=RequestMethod.DELETE, value= "/player/{id}")
public void deletePlayer(#PathVariable String id){
playerService.deletePlayer(id);
}*/
}
this is POJO class
Player.java
package io.anuj.springbootquickstart.topic;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.hibernate.annotations.GenericGenerator;
#Entity
/*#Table(name = "Player")*/
public class Player {
/*#Id
#GenericGenerator(name = "gene", strategy = "increment")
#GeneratedValue(generator = "gene")
#Column(name = "id")
private Long id;*/
#Id
#GenericGenerator(name = "gene", strategy = "increment")
#GeneratedValue(generator = "gene")
private long id;
private String team_id;
/*#Column(name = "name")*/
private String player_name;
/*#Column(name = "display_picture")*/
private String player_img_url;
/*#Column(name = "role")*/
private String player_role;
public Player(long id, String team_id, String player_name, String player_img_url, String player_role,
String player_batting_style, String player_bowling_style, String player_nationality, String player_dob) {
super();
this.id = id;
this.team_id = team_id;
this.player_name = player_name;
this.player_img_url = player_img_url;
this.player_role = player_role;
this.player_batting_style = player_batting_style;
this.player_bowling_style = player_bowling_style;
this.player_nationality = player_nationality;
this.player_dob = player_dob;
}
/* #Column(name = "batting_style")*/
private String player_batting_style;
/*#Column(name = "bowling_style")*/
private String player_bowling_style;
/*#Column(name = "nationality")*/
private String player_nationality;
/*#Column(name = "dob")*/
private String player_dob;
/*#Column(name = "teamId")*/
public Player(){
}
public String getTeam_id() {
return team_id;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public void setTeam_id(String team_id) {
this.team_id = team_id;
}
public String getPlayer_name() {
return player_name;
}
public void setPlayer_name(String player_name) {
this.player_name = player_name;
}
public String getPlayer_img_url() {
return player_img_url;
}
public void setPlayer_img_url(String player_img_url) {
this.player_img_url = player_img_url;
}
public String getPlayer_role() {
return player_role;
}
public void setPlayer_role(String player_role) {
this.player_role = player_role;
}
public String getPlayer_batting_style() {
return player_batting_style;
}
public void setPlayer_batting_style(String player_batting_style) {
this.player_batting_style = player_batting_style;
}
public String getPlayer_bowling_style() {
return player_bowling_style;
}
public void setPlayer_bowling_style(String player_bowling_style) {
this.player_bowling_style = player_bowling_style;
}
public String getPlayer_nationality() {
return player_nationality;
}
public void setPlayer_nationality(String player_nationality) {
this.player_nationality = player_nationality;
}
public String getPlayer_dob() {
return player_dob;
}
public void setPlayer_dob(String player_dob) {
this.player_dob = player_dob;
}
/*public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}*/
/*public Player(Long id, String team_id, String player_name, String player_img_url, String player_role,
String player_batting_style, String player_bowling_style, String player_nationality, String player_dob) {
super();
this.id = id;
this.team_id = team_id;
this.player_name = player_name;
this.player_img_url = player_img_url;
this.player_role = player_role;
this.player_batting_style = player_batting_style;
this.player_bowling_style = player_bowling_style;
this.player_nationality = player_nationality;
this.player_dob = player_dob;
}
*/
}
When i execute from json file it shows only last entry of json file. JSON file contains around 150 players but in databse is shows only last entry of the player. i think all the data is getting overwritten. Only last entry is shown of that json file in database. That is last player. Only one player which is last in json is there in database.
It's a little difficult to tell because you have a lot of commented out code that makes things harder to follow, but I think it is because of where you are creating the Player in your controller. Since you're doing this:
Player player = new Player()
outside of the loop, and Java is pass by value of reference, after the first time you addPlayer, you're just updating the same player with new data each time. You could confirm this if you simply debug your code and see if player has an ID after the first save call.
You'd probably want to do this to fix it:
for (int i = 0; i < data.size(); i++) {
Player player = new Player();
// rest of your code here
}
I am new to Neo4j and I want to connect a node (Person) with a node (Asset) but also, store the time that this connection has been created. I figured out that I have to use #RelatedtoVia annotation. I have followed the Spring cineasts tutorial ([https://github.com/spring-projects/spring-data-neo4j/tree/master/spring-data-neo4j-examples/cineasts][1] ) Although, everything works fine as far as the tests and the database population are concerned, I get weird results at the REST service. Here is my code:
Node Person
import org.neo4j.helpers.collection.IteratorUtil;
import org.springframework.data.neo4j.annotation.*;
import org.springframework.data.neo4j.template.Neo4jOperations;
import java.util.*;
#NodeEntity
public class Person {
#GraphId
Long id;
#Indexed
private String displayName;
#Indexed(unique = true, failOnDuplicate = true)
private Long personId;
private String firstName;
private String lastName;
private Date birthday;
private String aboutMe;
private String thumbnailURL;
private String email;
private enum gendertypes {male, female, other};
private gendertypes gender;
private String[] languages;
private boolean active;
public static final String CONSUMED = "CONSUMED";
//empty & full constructor
//getters&setters
#RelatedToVia(type = "CONSUMED", elementClass = ConsumedDate.class)
#Fetch
Iterable<ConsumedDate> consumedDates;
public ConsumedDate consumedDate(Neo4jOperations template, Asset asset, Date timestamp) {
final ConsumedDate consumedDate = template.createRelationshipBetween(this, asset, ConsumedDate.class, CONSUMED, false).consumedDate(timestamp);
return template.save(consumedDate);
}
public Collection<ConsumedDate> getConsumedDates() {
return IteratorUtil.asCollection(consumedDates);
}
}
Node Asset
import org.neo4j.helpers.collection.IteratorUtil;
import org.springframework.data.neo4j.annotation.*;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import static org.neo4j.graphdb.Direction.INCOMING;
#NodeEntity
public class Asset {
#GraphId
private Long id;
#Indexed(unique=true, failOnDuplicate = true)
private Long assetId;
private String description;
private String type;
private String[] tags;
public Asset() {}
public Asset(Long assetId, String description, String type, String[] tags) {
this.assetId = assetId;
this.description = description;
this.type = type;
this.tags = tags;
}
public Long getAssetId() {return assetId; }
public void setAssetId(Long assetId) {
this.assetId = assetId;
}
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[] getTags() {
return tags;
}
public void setTags(String[] tags) {
this.tags = tags;
}
#RelatedTo(type = "CONSUMED", direction = INCOMING)
Set<Person> persons;
#RelatedToVia(type="CONSUMED", elementClass=ConsumedDate.class, direction=INCOMING)
#Fetch
Iterable<ConsumedDate> consumedDates;
public Collection<Person> getPersons() {
return persons;
}
public Collection<ConsumedDate> getConsumedDates() {
Iterable<ConsumedDate> allConsumedDates = consumedDates;
return allConsumedDates == null ? Collections.<ConsumedDate>emptyList() : IteratorUtil.asCollection(allConsumedDates);
}
#Override
public String toString() {
return "An asset with ID " + assetId + " description " + description + " type " + type;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Asset asset = (Asset) o;
if (id == null) return super.equals(o);
return id.equals(asset.id);
}
#Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
Relationship Entity ConsumedDate
import org.springframework.data.neo4j.annotation.EndNode;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.RelationshipEntity;
import org.springframework.data.neo4j.annotation.StartNode;
import java.util.Date;
#RelationshipEntity(type = "CONSUMED")
public class ConsumedDate {
#GraphId
Long id;
#EndNode
Asset asset;
#StartNode
Person person;
Date timestamp;
public ConsumedDate consumedDate(Date timestamp){
this.timestamp=timestamp;
return this;
}
public Asset getAsset() {
return asset;
}
public Person getPerson() {
return person;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ConsumedDate consumedDate = (ConsumedDate) o;
if (id == null) return super.equals(o);
return id.equals(consumedDate.id);
}
#Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
Controller
import gr.ntua.sam.context.neo4j.AssetRepository;
import gr.ntua.sam.context.neo4j.LocationRepository;
import gr.ntua.sam.context.neo4j.PersonRepository;
import gr.ntua.sam.context.resources.*;
import com.wordnik.swagger.annotations.ApiOperation;
import org.neo4j.graphdb.NotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.text.ParseException;
import java.util.*;
import java.util.List;
#RestController
#Configuration
#EnableNeo4jRepositories
public class ContextController {
#Autowired
Neo4jTemplate template;
#Autowired
AssetRepository assetRepository;
#Autowired
PersonRepository personRepository;
#ApiOperation(value = "Show the available assets", response = Asset.class)
#RequestMapping(value = "/asset", method = RequestMethod.GET)
public ResponseEntity<List<Asset>> getAssets() throws NotFoundException {
List<Asset> results = assetRepository.all();
return new ResponseEntity<List<Asset>>(results, HttpStatus.OK);
}
#ApiOperation(value = "Create a new asset",response = Asset.class)
#RequestMapping(value = "/asset", method = RequestMethod.POST, consumes = "application/json")
public ResponseEntity<Asset> saveAsset(#RequestBody Asset asset) {
Asset savedAsset = assetRepository.save(asset);
return new ResponseEntity<Asset>(savedAsset, HttpStatus.CREATED);
}
//Persons
#ApiOperation(value = "Get a list of all the available Persons")
#RequestMapping(value = "/person", method = RequestMethod.GET)
public ResponseEntity<List<Person>> getPersons() throws ParseException {
List<Person> results = personRepository.all();
return new ResponseEntity<List<Person>>(results, HttpStatus.OK);
}
#ApiOperation(value = "Creates a new Person node to store information about a user", response = Person.class)
#RequestMapping(value = "/person", method = RequestMethod.POST, consumes = "application/json")
public ResponseEntity<Person> savePerson(#RequestBody Person person) {
Person savedPerson = personRepository.save(person);
return new ResponseEntity<Person>(savedPerson, HttpStatus.CREATED);
}
#ApiOperation(value = "Creates relationship between a Person and an Asset")
#RequestMapping(value = "/person/{personId}/consumes/", method = RequestMethod.POST, consumes = "application/json")
public ResponseEntity<Void> consumes(#PathVariable("personId") Long personId, #RequestBody LinkedAsset linkedAsset) {
Person person = personRepository.findByPersonId(personId);
List<Long> assetIds = linkedAsset.getAssetIDs();
for (Long assetId : assetIds) {
Asset currentAsset = assetRepository.findByAssetId(assetId);
Date date= linkedAsset.getTimestamp();
ConsumedDate consumedDate= person.consumedDate(template,currentAsset,date);
template.save(consumedDate);
}
return new ResponseEntity<Void>(HttpStatus.CREATED);
}
The problem is that when I create a relationship between a Person and an Asset, along with a timestamp (I have created the class LinkedAsset which serves as a JSON input model and has nothing to do with Neo4j) and then try to get through REST the person or the asset, all I get is something definitely not JSON with the person or the asset appearing infinite times. Is there a way to face this problem?
Thank you in advance!
I am trying to use GSON to convert a java object, in list format, to JSON, I have tried a few ways, but am running into the same error.
1st attempt
List<Techinv> techs = UserUtil.getTechModels(group, org);
Gson gson = new Gson();
String json = gson.toJson(techs);
2nd attempt
List<Techinv> techs = UserUtil.getTechModels(group, org);
Type listType = new TypeToken<List<Techinv>>() {}.getType();
Gson gson = new Gson();
String json = gson.toJson(techs, listType);
3rd attempt
List<Techinv> techs = UserUtil.getTechModels(group, org);
GsonBuilder gsonBuilder = new GsonBuilder();
new GraphAdapterBuilder()
.addType(Techinv.class)
.registerOn(gsonBuilder);
Gson gson = gsonBuilder.create();
String json = gson.toJson(techs);
All of the above fail, with either a stackoverflow error or a can't convert java int (one of the members in my Techinv class) to a java vector, all in the GSON library.
Please tell me I am missing something simple in all these examples :)
Techinv class (if required)
package org.cchit.inv.model;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
/**
* The persistent class for the techinv database table.
*
*/
#Entity
#NamedNativeQueries ({
#NamedNativeQuery(name="Techinv.deleteByOrgId",
query="DELETE FROM techinv where org_id = ?")
})
#NamedQueries ({
#NamedQuery(name="Techinv.removeUser",
query="UPDATE Techinv t SET user_id = 0 where t.id = :techid"),
#NamedQuery(name="Techinv.getAllByOrg",
query="SELECT p FROM Techinv p where p.organization.liferayId = :orgid"),
#NamedQuery(name="Techinv.getById",
query="SELECT t FROM Techinv t where t.id = :id"),
#NamedQuery(name="Techinv.getByProdOrg",
query="SELECT p FROM Techinv p where p.organization.liferayId = :orgid and p.product.id = :prodid"),
#NamedQuery(name="Techinv.delete",
query="DELETE FROM Techinv t where t.id = :id")
})
#Table(name="techinv")
public class Techinv implements Serializable {
private static final long serialVersionUID = 1L;
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#Column(name="mu_mask")
private long muMask;
#Column(name="mu_assigned_mask")
private long muAssignedMask;
#Column(name="mu_asked_assign_mask")
private long muAskedAssignedMask;
#Column(name="mu_cert_mask")
private long muWillCertMask;
#Column(name="mu_ask_will_cert_mask")
private long muAskedWillCertMask;
#Column(name="certType")
private String certType;
#Temporal(TemporalType.DATE)
#Column(name="Apply_date")
private Date applyDate;
#Temporal(TemporalType.DATE)
#Column(name="Cert_date")
private Date certDate;
#Lob()
private String notes;
//bi-directional many-to-one association to OrgUser
#ManyToOne
#JoinColumn(name="user_id")
private OrgUser orgUser;
//bi-directional many-to-one association to Organization
#ManyToOne
#JoinColumn(name="org_id")
private Organization organization;
//bi-directional many-to-one association to Product
#ManyToOne
#JoinColumn(name="prod_id")
private Product product;
//bi-directional many-to-one association to Certification
#ManyToOne
#JoinColumn(name="cert_id")
private Certification certification;
public void setCertification(Certification certification) {
this.certification = certification;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
public Techinv() {
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getNotes() {
return this.notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public OrgUser getOrgUser() {
return this.orgUser;
}
public void setOrgUser(OrgUser orgUser) {
this.orgUser = orgUser;
}
public Organization getOrganization() {
return this.organization;
}
public void setOrganization(Organization organization) {
this.organization = organization;
}
public long getMuMask() {
return muMask;
}
public void setMuMask(long muMask) {
this.muMask = muMask;
}
public long getMuAssignedMask() {
return muAssignedMask;
}
public void setMuAssignedMask(long muAssigned) {
this.muAssignedMask = muAssigned;
}
public Certification getCertification() {
return certification;
}
public long getMuWillCertMask() {
return muWillCertMask;
}
public void setMuWillCertMask(long muWillCertMask) {
this.muWillCertMask = muWillCertMask;
}
public long getMuAskWillCertMask() {
return muAskedWillCertMask;
}
public void setMuAskedWillCertMask(long muAskedWillCertMask) {
this.muAskedWillCertMask = muAskedWillCertMask;
}
/**
* This will set the question to true. Once asked and answered, this cannot be unset.
* #param mu
*/
public void setMuAskedAssignedMask(Mu mu) {
this.muAskedAssignedMask |= mu.getMask();
}
public boolean isCertified(Mu mu) {
return getCertification() != null && (getCertification().getMuMask() & mu.getMask()) > 0;
}
public boolean isAssigned(Mu mu) {
return (getMuAssignedMask() & mu.getMask()) > 0;
}
public boolean hasAskedToCertify(Mu mu) {
return isAssigned(mu) && !isCertified(mu) && (getMuAskWillCertMask() & mu.getMask()) > 0;
}
public boolean isWillCertify(Mu mu) {
return hasAskedToCertify(mu) && (getMuWillCertMask() & mu.getMask()) > 0;
}
public boolean hasMu(Mu mu) {
return (getMuMask() & mu.getMask()) > 0;
}
public boolean hasAskedToAssign(Mu mu) {
return (muAskedAssignedMask & mu.getMask()) > 0;
}
public String getCertType() {
return certType;
}
public void setCertType(String certType) {
this.certType = certType;
}
public Date getApplyDate() {
return applyDate;
}
public void setApplyDate(Date applyDate) {
this.applyDate = applyDate;
}
public Date getCertDate() {
return certDate;
}
public void setCertDate(Date certDate) {
this.certDate = certDate;
}
}
You should check for circular references in your serialized classes and mark the appropriate properties #Transient. Post your TechModel class if you want help with that.
edit: as using #Transient is not an option for you , use Gson's #Expose .
From the GSON user guide :
This feature provides a way where you can mark certain fields of your
objects to be excluded for consideration for serialization and
deserialization to JSON. To use this annotation, you must create Gson
by using new
GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(). The
Gson instance created will exclude all fields in a class that are not
marked with #Expose annotation.
Type listType = new TypeToken<ArrayList<Techinv>>() {}.getType();
You may try out the standard implementation of the Java API for JSON processing which is part of J2EE.
I don't have access to your beans OrgUser, Organization, Product, and Certification. So I assume that each of them comprises an id and a name.
For your List<Techinv> techList.
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
List<Techinv> techList = new ArrayList<Techinv>();
for (int i = 1; i <= 3; i++) {
Techinv tech = new Techinv(i, 1L, 2L, 3L, 4L, 5L, "cert",
new Date(), new Date(), "notes", new OrgUser(i, "orguser"),
new Organization(i, "organization"), new Product(i,
"product"), new Certification(i, "certification"));
techList.add(tech);
}
Techinv[] techArr = techList.toArray(new Techinv[techList.size()]);
JsonArrayBuilder techArrBuilder = Json.createArrayBuilder();
for (Techinv tech : techArr) {
JsonObjectBuilder jsonObject = Json.createObjectBuilder()
.add("id", tech.getId())
.add("muMask", tech.getMuMask())
.add("muAssignedMask", tech.getMuAssignedMask())
.add("muAskedAssignedMask", tech.getMuAskedAssignedMask())
.add("muWillCertMask", tech.getMuWillCertMask())
.add("muAskedWillCertMask", tech.getMuAskedWillCertMask())
.add("certType", tech.getCertType())
.add("applyDate", sdf.format(tech.getApplyDate()))
.add("certDate", sdf.format(tech.getCertDate()))
.add("notes", tech.getNotes())
.add("OrgUser", Json.createObjectBuilder()
.add("id", tech.getOrgUser().getId())
.add("name", tech.getOrgUser().getName()))
.add("Organization", Json.createObjectBuilder()
.add("id", tech.getOrganization().getId())
.add("name", tech.getOrganization().getName()))
.add("Product", Json.createObjectBuilder()
.add("id", tech.getProduct().getId())
.add("name", tech.getProduct().getName()))
.add("Certification", Json.createObjectBuilder()
.add("id", tech.getCertification().getId())
.add("name", tech.getCertification().getName()));
techArrBuilder.add(jsonObject);
}
JsonArray jsonArray = techArrBuilder.build();
Map<String, Object> prop = new HashMap<String, Object>() {
{
put(JsonGenerator.PRETTY_PRINTING, true);
}
};
JsonWriter jsonWriter = Json.createWriterFactory(prop).createWriter(System.out);
jsonWriter.writeArray(jsonArray);
jsonWriter.close();
The output should be:
[
{
"id":1,
"muMask":1,
"muAssignedMask":2,
"muAskedAssignedMask":3,
"muWillCertMask":4,
"muAskedWillCertMask":5,
"certType":"cert",
"applyDate":"2014-04-03",
"certDate":"2014-04-03",
"notes":"notes",
"OrgUser":{
"id":1,
"name":"orguser"
},
"Organization":{
"id":1,
"name":"organization"
},
"Product":{
"id":1,
"name":"product"
},
"Certification":{
"id":1,
"name":"certification"
}
},
{
"id":2,
"muMask":1,
"muAssignedMask":2,
"muAskedAssignedMask":3,
"muWillCertMask":4,
"muAskedWillCertMask":5,
"certType":"cert",
"applyDate":"2014-04-03",
"certDate":"2014-04-03",
"notes":"notes",
"OrgUser":{
"id":2,
"name":"orguser"
},
"Organization":{
"id":2,
"name":"organization"
},
"Product":{
"id":2,
"name":"product"
},
"Certification":{
"id":2,
"name":"certification"
}
},
{
"id":3,
"muMask":1,
"muAssignedMask":2,
"muAskedAssignedMask":3,
"muWillCertMask":4,
"muAskedWillCertMask":5,
"certType":"cert",
"applyDate":"2014-04-03",
"certDate":"2014-04-03",
"notes":"notes",
"OrgUser":{
"id":3,
"name":"orguser"
},
"Organization":{
"id":3,
"name":"organization"
},
"Product":{
"id":3,
"name":"product"
},
"Certification":{
"id":3,
"name":"certification"
}
}
]