#java #json #hibernate #api #one-to-many
#java #json #спящий режим #API #один ко многим
Вопрос:
У меня возникли проблемы с получением упорядоченных данных в конечной точке java API из интерфейса react.
В частности, это массив JSON, который содержит внутри рекурсивно объекты и массивы в древовидной структуре, как в примере, написанном ниже
Вопрос: как я могу получить свой массив дочерних элементов, который отображается с помощью Hibernate внутри набора дочерних элементов, в правильном порядке? Вероятно, мне не хватает какой-то аннотации hibernate или чего-то еще
Если я перейду в режим отладки, я обнаружил, что сразу после ввода в первую строку кода метода savePeopleByDynastyId() набор дочерних элементов внутри PeopleList потерял порядок.
(правильный порядок, который я хочу достичь для объектов Person: child1, child2, child3)
Это единственный способ отправить их с и Id уже (я бы предпочел этого избежать)? Если да, какую аннотацию я должен добавить к @OneToMany private Set<Person> subChildren
для достижения этой цели? Я пробовал @OrderBy(value = "id")
, но это не работает
Любая помощь приветствуется!
Данные JSON, отправленные с помощью Postman для имитации запроса POST: http://localhost:8080/api/dynasty/people
[
{
name: father,
age: 50,
subChildren : [
{
name: child1,
age: 30,
subChildren : []
},
{
name: child2,
age: 28,
subChildren : []
},
{
name: child3,
age: 26,
subChildren : []
},
]
}
]
Person.java:
@Entity
@Table(name="Person")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String name;
private Integer age;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="ID_PARENT")
@JsonIgnore
private Person parent;
@OneToMany(mappedBy="parent", fetch = FetchType.EAGER)
@OrderBy(value = "id")
private Set<Person> subChildren = new LinkedHashSet<Person>();
public Person(){}
//Getter and Setter
}
DynastyController.java:
@RestController
@CrossOrigin
@RequestMapping("/api/dynasty")
public class DynastyController {
@PostMapping("/people")
public ResponseEntity<?> savePeopleByDynastyId(@RequestBody Iterable<Person> peopleList, BindingResult result){
Iterable<Person> newPeopleList = null;
for (Person person : peopleList) {
//intention : cycle through each person of subChildren array recursively and persist each of his person
}
ResponseEntity<Iterable<Person>> responseEntity= new ResponseEntity<>(newPeopleList, HttpStatus.CREATED);
return responseEntity;
}
}
Комментарии:
1. Идентификатор orderby не работает, возможно, потому, что у вас нет идентификатора в списке ответов. Попробуйте включить идентификатор в ответ и проверить.
2. спасибо за ответ. Я пробовал это с идентификатором в списке ответов, но это не сработало. Я не указывал id в вопросе, потому что я хотел бы найти решение без отправки id из интерфейса, потому что я считаю, что они должны быть сгенерированы на бизнес-уровне, когда объект сохраняется в БД
Ответ №1:
Я думаю, что проблема заключается в десериализации, выполненной Джексоном. Он заменяет коллекцию на обычную HashSet
вместо добавления к существующей LinkedHashSet
. Попробуйте использовать LinkedHashSet
тип как объявленный тип в сущности.
Комментарии:
1. к сожалению, я не могу изменить набор в LinkedHashSet, потому что он не будет компилироваться, для Hibernate требуется: тип атрибута «От одного до многих» должен быть [java.util. Коллекция, java.util. Список, java.util.Set]
2. Вы проверяли, является ли тип набора все еще связанным набором хэшей после десериализации?
3. Путем отладки в вашем методе контроллера и проверки типа объекта переменной.
4. Я подтверждаю, что это HashSet, что я могу сделать?
5. Согласно документации Hibernate путем добавления аннотации @OrderBy, набор должен быть преобразован в LinkedHashSet, упорядоченный по указанному значению, поэтому вы говорите, что проблема в том, что перед тем, как действовать в режиме гибернации, Джексон десериализует массив JSON в HashSet