0

In my Spring Boot app I am using hibernate. I have many to one relationship as follows:-

@Entity
@Table(name = "STUDENT")
@JsonIdentityInfo(
        generator = ObjectIdGenerators.PropertyGenerator.class,
        property = "id")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String name;

    @Column
    private int mobile;

    @ManyToOne( fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "DEPT_ID", nullable = false)
    private Department department;

    public Long getId() {
        return id;
    }

    public void setId(Long id){
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getMobile() {
        return mobile;
    }

    public void setMobile(int mobile) {
        this.mobile = mobile;
    }

    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", mobile=" + mobile +
                ", department=" + department +
                '}';
    }
}

And as:-

@Entity
@Table(name = "DEPARTMENT")
@JsonIdentityInfo(
        generator = ObjectIdGenerators.PropertyGenerator.class,
        property = "id")
public class Department {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String name;

    @OneToMany(mappedBy = "department", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<Student> studentList=new ArrayList<Student>();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Student> getStudentList() {
        return studentList;
    }

    public void setStudentList(List<Student> studentList) {
        this.studentList = studentList;
    }
}

For Department's fetch = FetchType.LAZY and fetch = FetchType.EAGER both works fine.

To understand better I was switching Student's @ManyToOne( fetch = FetchType.EAGER) to @ManyToOne( fetch = FetchType.LAZY). It breaks with the following error when FetchType.LAZY:-

"Type definition error: [simple type, class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.ArrayList[0]->com.myjavablog.model.Student["department"]->com.myjavablog.model.Department$HibernateProxy$w9HG3Rv0["hibernateLazyInitializer"])"

Why is it happening? Why can't I do fetch type lazy for student? Thanks in advance!

masiboo
  • 4,537
  • 9
  • 75
  • 136

1 Answers1

0

You can Ignore to produce JSON output of property by

@JsonIgnore 

Or If you have any lazy loaded properties having a relationship. You can use this annotation at top of the property.

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) 

This fixed my problem. Thanks for the suggestion by the community.

masiboo
  • 4,537
  • 9
  • 75
  • 136