Десериализатор Json в Spring Boot – Как выполнить десериализацию и внутренние отношения

Я работаю над проектом Spring Boot, которому необходимо преобразовать JSON в Entity для сохранения в базе данных postgresql. У меня есть некоторые отношения, ссылающиеся на себя, которые не знают, как десериализовать и сохранить в БД. У меня есть пользователи, у которых есть какие-то отношения с другими пользователями. Например, пользователь А является клиентом пользователя Б.

Давайте посмотрим пример кода, чтобы лучше понять...

У меня есть JSON для сохранения информации в БД.

{
  id: 1,
  name: "myName"
  relations:[
     {
       "user_id": "2",
       "relation": "relation_name"
     },
     {
       "user_id": "3",
       "relation": "other_relation_name"
     }
  ]
}

У меня есть следующие классы (пример кода)


@Entity
@Data
public class User {
    @Id
    private Long id;
    private String name;
    @OneToMany(mappedBy = "user_id_parent")
    private List<UserRelation> relations;
}

@Entity
@Data
public class UserRelation {
    @Id
    @ManyToOne(targetEntity = User.class)
    @JoinColumn(name = "user_id_parent", referencedColumnName = "id", nullable = false)
    private Long user_id_parent;
    @Id
    @JsonProperty("user_id")
    private Long user_id_child;
    private String relation;
}

Для десериализации и сохранения в БД я делаю это

ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(json.toString(), User.class);

// user have [User(id=1, name:"myName", relations=[UserRelation(user_id_child=2, relation = "relation_name", user_id_parent=null)]]

userRepository.save(user);

Но у меня есть эта ошибка:

Unable to find com.compani.project.domain.UserRelation with id UserRelation(user_id_child=2, relation=null, user_id_parent=null)

Я понятия не имею, как хорошо выполнить эту задачу. Есть идеи или предложения, что можно сделать?

РЕДАКТИРОВАТЬ

Как предложил @Wladimir Diskowski, это работа для меня.

@Entity
@Data
public class User {
    @Id
    private Long id;
    private String name;
    @OneToMany(mappedBy = "userParent", cascade =  { CascadeType.PERSIST, CascadeType.MERGE })
    private List<UserRelation> relations;
}

@Entity
@Data
public class UserRelation {
    @Id
    @ManyToOne(targetEntity = User.class)
    @JoinColumn(name = "user_id_parent", referencedColumnName = "id", nullable = false)
    @JsonIgnore
    private User userParent;
    @Id
    @JsonProperty("user_id")
    private Long user_id_child;
    private String relation;
} 

ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(json.toString(), User.class);
user.relations.foreach(r -> r.setUserParent(user));
userRepository.save(user);

Но у меня есть эта ошибка

Unable to find com.compani.project.domain.UserRelation with id com.compani.project.domain.UserRelationId@356bed68

Ваше поле user_id_parent отмечено nullable = false, но вы пытаетесь сохранить с нулевым значением.

Anton Kozub 12.04.2024 14:30

Вам следует установить user_id_parent равным 2 и сначала сохранить UserRelation или определить Cascade Persist по сущности User.

Wladimir Diskowski 12.04.2024 14:43

@WladimirDiskowski, я думаю, что user_id_parent должен быть 1, а 2 будет user_id_child. Также я определяю Cascade Persist в сущности User и не работает.

xabikip 12.04.2024 15:04

@AntonKozub да, я знаю. user_id_parent должен иметь значение nullable = false, потому что это идентификатор пользователя (в примере json id:1), но я не знаю, как получить этот идентификатор и поместить UserRelation .user_id_parent

xabikip 12.04.2024 15:11
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
4
82
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Что я имею в виду:


@Entity
@Data
public class User {
    @Id
    private Long id;
    private String name;
    @OneToMany(mappedBy = "userParent", cascade = { CascadeType.PERSIST, CascadeType.MERGE })
    private List<UserRelation> relations;
}

@Entity
@Data
public class UserRelation {
    @ManyToOne(targetEntity = User.class)
    @JoinColumn(name = "user_id_parent", referencedColumnName = "id", nullable = false)
    @JsonIgnore
    private User userParent;
    @Id
    @JsonProperty("user_id")
    private Long user_id_child;
    private String relation;
} 
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(json.toString(), User.class);
user.relations.foreach(r -> r.setUserParent(user));
userRepository.save(user);

Я написал, как вы говорите, но у меня есть еще одна ошибка (я отредактировал вопрос).

xabikip 12.04.2024 16:20

я исправил свой ответ

Wladimir Diskowski 12.04.2024 16:56

И если пользователь уже существует в базе данных и вы производите обновление, вам также понадобится CascadeType.MERGE.

Wladimir Diskowski 12.04.2024 17:01

Другие вопросы по теме