Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StackOverflow Exception while using Hibernate and Jackson on bi-directional objects

I am trying some hibernate.The following is the pojo I am using,

@Entity
@Table(name = "person")
public class Person {

    @Id
    @GeneratedValue
    @Column(name = "person_id")
    private long person_id;


    @Column(name = "name")
    private String name;


    @Column(name = "Address")
    private String Address;


    @OneToMany(fetch = FetchType.EAGER, mappedBy = "person" )
    private Set<Phone> phone;

        //Getters ande Setters

}


@Entity
@Table(name = "phone")
public class Phone{

    @Id
    @GeneratedValue
    @Column(name = "phone_id")
    private long phone_id;


    @Column(name = "name")
    private String name;

         @ManyToOne(cascade = CascadeType.MERGE,fetch = FetchType.EAGER)
    @JoinColumn(name = "person_id")
    private Person person ;

        //Getters ande Setters


}

What I want is when I fetch a record from person and need corresponding all phone details. (Like Select * from person) I have around 1360 data in person and nearly double in phone. But for some reason error is thrown. I am not able to see full error stack . Below is the error I am getting.

at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:505) ~[jackson-databind-2.4.6.jar:2.4.6] at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:639) ~[jackson-databind-2.4.6.jar:2.4.6] at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152) ~[jackson-databind-2.4.6.jar:2.4.6] at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:505) ~[jackson-databind-2.4.6.jar:2.4.6] at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:639) ~[jackson-databind-2.4.6.jar:2.4.6] at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152) ~[jackson-databind-2.4.6.jar:2.4.6] at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:117) ~[jackson-databind-2.4.6.jar:2.4.6] at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23) ~[jackson-databind-2.4.6.jar:2.4.6] at .....

I was not able to post all error that I got

like image 809
Learner Avatar asked Dec 14 '22 07:12

Learner


2 Answers

Using JsonManagedReference and JsonBackReference annotations may solve your problem.

While jackson trying to convert objects to json, visits objects and their attributes. So if objects have bi-directional relations, for jackson we need to think about cyclic dependencies. Jackson starts serialize person and see the phone list and take a phone from list and start serialize phone and sees person in phone and take person from phone and start serilize it bla bla bla so this is an endless loop. If jackson sees these annotations, stops and breaks the loop.

Give it a try as below code;

@Entity
@Table(name = "person")
public class Person {

    @Id
    @GeneratedValue
    @Column(name = "person_id")
    private long person_id;    

    @Column(name = "name")
    private String name;

    @Column(name = "Address")
    private String Address;
    @JsonManagedReference
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "person" )
    private Set<Phone> phone;

    // Getters and Setters

}

@Entity
@Table(name = "phone")
public class Phone{

    @Id
    @GeneratedValue
    @Column(name = "phone_id")
    private long phone_id;

    @Column(name = "name")
    private String name;

    @ManyToOne(cascade = CascadeType.MERGE,fetch = FetchType.EAGER)
    @JoinColumn(name = "person_id")
    @JsonBackReference
    private Person person;

    // Getters and Setters

}
like image 200
Yusuf K. Avatar answered Mar 22 '23 22:03

Yusuf K.


You can alternatively use @JsonIdentityInfo on classes

@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
@Table(name = "phone")
public class Phone {

}

@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
@Table(name = "person")
public class Person {

}
like image 41
biology.info Avatar answered Mar 22 '23 23:03

biology.info