1

I have trying spring rest with hibernate, JPA and JSON. I have to entities like below:

University.java

@Entity()
@Table(name = "university")
public class University extends BaseEntity {
    private String uniName;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @JoinColumn(name = "university_id", foreignKey = @ForeignKey(name = "university_id"))
    private Collection<Student> students;

    //setters and getters
}

Student.java

@Entity
@Table(name = "student")
public class Student extends BaseEntity {
    private String stuName;

    @ManyToOne(fetch = FetchType.EAGER)
    @JsonIgnoreProperties("students")
    private University university;

    //setters and getters
}

I have this dumy values in my db.

[
  {
    "id": 1,
    "uniName": "uni1",
    "students": [
      {
        "id": 1,
        "stutName": "st1",
        "university": {
          "id": 1,
          "uniName": "uni1"
        }
      },
      {
        "id": 2,
        "stutName": "st2",
        "university": {
          "id": 1,
          "uniName": "uni1"
        }
      }
    ]
  }
]

first try: When I try to update the university with its student, there is no success and this is my hibernate log

Hibernate:
    select
        university0_.id as id1_5_1_,
        university0_.uniName as uniName2_5_1_,
        students1_.university_id as universi3_4_3_,
        students1_.id as id1_4_3_,
        students1_.id as id1_4_0_,
        students1_.stuName as stuName2_4_0_,
        students1_.university_id as universi3_4_0_
    from
        university university0_
    left outer join
        student students1_
            on university0_.id=students1_.university_id
    where
        university0_.id=?
Hibernate:
    update
        student
    set
        stuName=?,
        university_id=?
    where
        id=?
Hibernate:
    update
        university
    set
        uniName=?
    where
        id=?
Hibernate:
    update
        student
    set
        stuName=?,
        university_id=?
    where
        id=?

second try: But when I Post same data for second time it is successful and the hibernate log is

Hibernate:
    select
        university0_.id as id1_5_1_,
        university0_.uniName as uniName2_5_1_,
        students1_.university_id as universi3_4_3_,
        students1_.id as id1_4_3_,
        students1_.id as id1_4_0_,
        students1_.stuName as stuName2_4_0_,
        students1_.university_id as universi3_4_0_
    from
        university university0_
    left outer join
        student students1_
            on university0_.id=students1_.university_id
    where
        university0_.id=?
Hibernate:
    select
        student0_.id as id1_4_0_,
        student0_.stuName as stuName2_4_0_,
        student0_.university_id as universi3_4_0_
    from
        student student0_
    where
        student0_.id=?
Hibernate:
    select
        student0_.id as id1_4_0_,
        student0_.stuName as stuName2_4_0_,
        student0_.university_id as universi3_4_0_
    from
        student student0_
    where
        student0_.id=?
Hibernate:
    update
        student
    set
        university_id=?
    where
        id=?
Hibernate:
    update
        student
    set
        university_id=?
    where
        id=?

Which is different from first one !!

What I am doing wrong in my hibernate annotations, or if I have missing something in my JSON annotation why the second try working.

UPDATE: this is my edit service.

@Override
@Transactional/*(propagation = Propagation.NESTED)*/
public T edit(T entity) throws Exception {
    return entityManager.merge(entity);
}

any help and advice is appreciated.

Abdullah Khan
  • 12,010
  • 6
  • 65
  • 78
Ali Akbarpour
  • 958
  • 2
  • 18
  • 35
  • 1
    Post the code that is persisting the data. – Abdullah Khan Oct 15 '17 at 08:12
  • @ Abdullah Khan I update my question – Ali Akbarpour Oct 15 '17 at 08:16
  • 1
    Your mapping is wrong. Read the Hibernate manual to know how to correctly map a bidirectional OneToMany association. – JB Nizet Oct 15 '17 at 08:16
  • I have JSON serializing issue with hibernate manual , I couldn't find solution to give me the proper solution about JSON serializing, I have asked in this one https://stackoverflow.com/questions/46684015/json-serializing-and-deserializing-with-hibernate-jpa-to-have-parent-object-into – Ali Akbarpour Oct 15 '17 at 08:21
  • JSON serialising is absolutely nothing to do with Hibernate persistence. –  Oct 15 '17 at 08:31

2 Answers2

1

Try to update your entities like so

@Entity
@Table(name = "university")
public class University extends BaseEntity {

    private String uniName;

    @OneToMany(mappedBy = "university", ...) // Check the mappedBy property
    private Collection<Student> students;

    //setters and getters

}

@Entity
@Table(name = "student")
public class Student extends BaseEntity {

    private String stuName;

    @ManyToOne(fetch = FetchType.EAGER)
    @JsonIgnoreProperties("students")
    private University university; // university is bidirectionally mapped to Student 

    //setters and getters
}
Abdullah Khan
  • 12,010
  • 6
  • 65
  • 78
  • I need have both side eagerly and with JSON serializing it have circular, and if I add @JsonIdentity info json serializing is something that not fit my requirements – Ali Akbarpour Oct 15 '17 at 08:32
  • For this issue use a different DTO class to map your JSON to the method paramater. – Abdullah Khan Oct 15 '17 at 08:33
  • please be more specific how it would be – Ali Akbarpour Oct 15 '17 at 08:35
  • Create a class `UserDTO.java` and have only the specific user fields in the `UserDTO.java` class that you want to serialize. Have your JSON mapped to `UserDTO.java` class instead of the original `User` class. Check out [this](https://stackoverflow.com/a/35079306/3094731) and [this](https://dzone.com/articles/testing-data-transfer-object-and-rest-controllers). – Abdullah Khan Oct 15 '17 at 08:37
  • Did you fix your problem? – Abdullah Khan Oct 16 '17 at 07:00
1

after changing my entities like below it worked perfectly.

University.java

@Entity()
@Table(name = "university")
public class University extends BaseEntity {
    private String uniName;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @JoinColumn(name = "university_id")
    private Collection<Student> students;

    //setters and getters
}

Student.java

 @Entity
    @Table(name = "student")
    public class Student extends BaseEntity {
        private String stuName;

        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "university_id",updatable = false,insertable = false)
        @JsonIgnoreProperties(value = "students", allowSetters = true)
        private University university;

        //setters and getters
    }

I hope this help someone else that have same issue.

Ali Akbarpour
  • 958
  • 2
  • 18
  • 35