Search code examples
javaspring-boothibernatejpajackson

Json Deserializer in Spring Boot - How to make deserialization and self relations


I'm working in a Spring Boot project that need convert JSON to Entity to save in a postgresql database. I have some self referencing relations, that didn`t konw how to deserialize and save in DB. I have a Users that have some kind of relations wiht other users. For example User A is client of User B.

Let's see example code to understand better...

I have following JSON to save info into DB

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

I have following classes (Sample Code)


@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;
}

For deserialize and save in DB I do this

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);

But, I have this error:

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

I have no idea how to do well this task. Any ideas or suggestions to do?

EDIT

Like @Wladimir Diskowski suggested, this work for me.

@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);

But i have this error

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

Solution

  • What I mean:

    
    @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);