Issue
I am creating application called as hostel management system using spring boot application using JPA repo. I have added one hostel. then i added rooms, then update hostel to update join table entries. Now I am trying to fetching hostel. Unable to fetch hostel data, it shows :
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
lots of line.............
I have uploaded this project on gitHub : https://github.com/aniketkadu0/hms_new.git
Hostel.java
@Table(name = "hostels")
public class Hostel implements Cloneable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
int hostelId;
String hostelName;
String hostelAddress;
String contactPersonName;
String contactPersonNumber;
@OneToMany
@JoinTable(joinColumns = @JoinColumn(
name = "hostel_id",
referencedColumnName = "hostelId"
),
inverseJoinColumns = @JoinColumn(
name = "room_number",
referencedColumnName = "roomNumber"
))
List<Room> rooms;
@OneToOne
Mess mess;
@OneToMany
List<Notice> notices;
}
Room.java
@Table(name = "rooms")
public class Room {
@Id
int roomNumber;
int noOfOccupants;
@OneToOne
RoomDetail roomDetail;
@OneToOne
Hostel hostel;
@OneToMany
List<Student> student;
}
RoomDetail.java
@Entity
public class RoomDetail {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
int roomDetailId;
String roomName;
int price;
int maxOccupants;
}
hostel JSON
{
"hostelId": 1,
"hostelName": "Hostel no. 1 Boys Hostel",
"hostelAddress": "building no. 5",
"contactPersonName": "XYZ",
"contactPersonNumber": "9999977777",
"rooms": null,
"mess": null,
"notices": null
}
Room JSON
{
"noOfOccupants" : 0,
"roomDetail" : {
"roomDetailId" : 1
} ,
"hostel" : {
"hostelId" : 1
}
}
AdminService.java
@Service
public class AdminService {
@Autowired
HostelDAO hostelDAO;
@Autowired
RoomDAO roomDAO;
@Autowired
RoomDetailDAO roomDetailDAO;
public Hostel addHostel(Hostel hostel) {
return hostelDAO.save(hostel);
}
public Room addRoom(Room room,int qty,int firstRoomNumber){
Optional<Hostel> hostel = hostelDAO.findById(room.getHostel().getHostelId());
Optional<RoomDetail> roomDetail = roomDetailDAO.findById(room.getRoomDetail().getRoomDetailId());
room.setHostel(hostel.get());
room.setRoomDetail(roomDetail.get());
List<Room> rooms = new ArrayList<>();
room.setRoomNumber(firstRoomNumber);
System.out.println(room);
firstRoomNumber--;
int i = 1;
while( i <= qty) {
Room newRoom = new Room(room.getRoomNumber(),
room.getNoOfOccupants(),room.getRoomDetail(),
room.getHostel(),room.getStudent());
newRoom.setRoomNumber(firstRoomNumber + i);
rooms.add(newRoom);
i++;
}
roomDAO.saveAll(rooms);
hostel.get().setRooms(rooms);
hostelDAO.save(hostel.get());
return null;
}
public List<Hostel> getHostelData() {
return hostelDAO.findAll();
}
}
Solution
The problem with serializing a Hostel will be that your Hostel has rooms which point back at the same Hostel. There are many ways to tell your JSON serializer how to handle it. Assuming you are using Jackson, the easiest might be to add the @JsonIgnore annotation on one side that you don't need serialized. Ie:
@Table(name = "rooms")
public class Room {
@Id
int roomNumber;
int noOfOccupants;
@OneToOne
RoomDetail roomDetail;
@OneToOne
@JsonIgnore
Hostel hostel;
@OneToMany
List<Student> student;
}
You will have to look at all your circular references - the entire graph really - and decide what you really want serialized when fetching through REST calls, and how your clients might need to handle the data.
Answered By - Chris
Answer Checked By - Senaida (JavaFixing Volunteer)