I have a problem when i try to update a questionary from a json. I need to store some data in db from a json. I use multiple entity for set the questionary and some @onetomany for create foreignkey.
The first time i store the data all is good, hibernate store correctly all the data whit autogenerated id, when i try to load again a json whit some changes on the child table, the id of the Questionary persist correctly (becouse is a field obteined dircetly from json) the questions and answer change id though i set the values.
I hope you undrestand what i mean.
this is my entity:
public class Questionary implements Serializable {
private static final long serialVersionUID = -6101283729971360969L;
/**
* Primary key from JSON
*/
@Id
@JsonIgnore
private int id;
@Version
private Long version;
private String desc;
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name = "idQuest")
@OnDelete(action = OnDeleteAction.CASCADE)
@OrderBy("identityQuestion ASC")
private Set<Question> question;
public class Question implements Serializable {
private static final long serialVersionUID = -6101283729971360969L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
@Version
private Long version;
private int identityQuestion;
private String text;
private long idTipoTag;
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name = "idQuestion")
@OnDelete(action = OnDeleteAction.CASCADE)
@OrderBy("identityAnswer ASC")
private Set<Answer> answer;
this is the method on controller
@RestController
@Slf4j
public class QuestionaryController {
@Autowired
private QuestionaryRepository questionaryRepository;
@Autowired
private AnswerRepository answerRepository;
@RequestMapping(value = "/save", method = RequestMethod.POST)
public void saveQuest(@RequestBody List<QuestionaryDTO> questDTO) {
for (QuestionaryDTO questionaryDTO : questDTO) {
/**
* find value in db
*/
Questionary quest = questionarioRepository.findById(questionarioDTO.getId());
if (quest != null) {
quest.setDescrizione(questionarioDTO.getDescrizione());
Set<QuestionDTO> listQuestion = QuestionaryDTO.getQuestion();
Set<Question> questionDB = quest.getQuestion();
ArrayList<QuestionDTO> l = new ArrayList<QuestionDTO>(listQuestion);
ArrayList<Question> c = new ArrayList<Question>(questionDB);
int i = -1;
for(int j=0; j<l.size();j++) {
i++;
Question dom = c.get(i);
dom.setIdentityQuestion(l.get(j).getId());
dom.setIdTipoTag(l.get(j).getIdTipoTag());
dom.setText(l.get(j).getText());
questionDB.add(dom);
ecc...
}
quest.setquestion(questionDB);
questionariyRepository.save(quest);
} else {
/**
* Questionary
*/
Questionary questn = new Questionary();
questn.setTitle(questionaryDTO.getTitle());
questn.setId(questionaryDTO.getId());
/**
* Questions
*/
Set<QuestionDTO> listQuestion = questionaryDTO.getQuestion();
Set<Question> QuestionDB = new HashSet<>();
for (QuestionDTO questionDTO : listQuest) {
Question que = new Question();
que.setIdentityQuestion(questionDTO.getId());
que.setText(QuestionDTO.getText());
que.setIdTipoTag(QuestionDTO.getIdTipoTag());
QuestionDB.add(que);
/**
* Answers
*/
Set<AnswerDTO> listAnswers = AnswerDTO.getAnswers();
Set<Answers> listAnswersDB = new HashSet<>();
for (AnswersDTO AnswersDTO : listAnswer) {
Answers ans = new Answers();
ans.setIdentityAnswer(AnswerDTO.getId());
asn.setText(AnswerDTO.getText());
listAnswersDB.add(ans);
}
dom.setAnswer(listAnswersDB);
}
questn.setQuestion(QuestionDB);
questionarioRepository.save(questn);
}
}
}
This is DTO entity
public class QuestionariyDTO implements Serializable{
private static final long serialVersionUID = -1886966747159529916L;
private int id;
private int identityQuestionary;
private String title;
private Set<QuestionDTO> questions;
}
public class QuestionDTO implements Serializable {
private static final long serialVersionUID = -1886966747159529916L;
private int id;
private String text;
private Long idTipoTag;
private Set<AnswerDTO> answers;
}
public class AnswerDTO implements Serializable{
private static final long serialVersionUID = -1886966747159529916L;
private Long id;
private String text;
private Long identityAnswer;
}
this in an example of json structure
[
{
"id": 1,
"title": "TITLE",
"questions": [
{
"id": 1, <--- this id is only "identityQuestion" on db is not the primary key
"text": "some text",
"idTipoTag": 1,
"answers": [
{
"id": 1, <--- this id is only "identityAnswer" on db is not the primary key
"text": "answ 1"
},
{
"id": 2,
"text": "answ 2"
},
{
"id": 3,
"text": "answ 3"
},
{
"id": 4,
"text": "answ 4"
}
]
},
{
"id": 2,
"text": "some text",
"idTipoTag": 1,
"answers": [
...
.
.
.
.
.
]
},
...
]
}
]
The cause of save in random order is the HashSet, they don't have a order and always save date in random position.
I have just converted all the Set value into List. After do it when i go to instance the object i use a LinkedList for order value!
this works smooth for me!
here is an example:
Before:
Set<QuestionDTO> listQuestion = questionaryDTO.getQuestion();
Set<Question> QuestionDB = new HashSet<>();
After:
List<QuestionDTO> listQuestion = questionaryDTO.getQuestion();
List<Question> QuestionDB = new LinkedList<>();