วัตถุโดเมนที่ส่งคืนจาก RestController ทำให้เกิดข้อผิดพลาด AJAX Custom Model Object ใช้งานได้

ฉันมีปัญหาใน SpringMVC RestController ที่เขียนผลลัพธ์ JSON:

1) เมื่อฉันส่งคืน อ็อบเจ็กต์โดเมนด้านล่าง ActivitiesT ฉันได้รับข้อผิดพลาดเซิร์ฟเวอร์ภายใน AJAX 500 บนฝั่งไคลเอ็นต์

@RequestMapping("/participant/activityForEvent") 
public ActivitiesT getActivityForGuiEventId() throws Exception {
    ActivitiesT activitiesT = participantService.getActivity();
    return activitiesT;
}

อ็อบเจ็กต์โดเมน ActivitiesT ที่สร้างโดย Hiberate:

@Entity
@Table(name = "activities_t", schema = "public")
public class ActivitiesT implements java.io.Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private int id;
    //... etc...
}

2) แต่เมื่อฉันส่งคืน POJO แบบกำหนดเอง วิธี AJAX ก็ใช้งานได้ มันเกือบจะเหมือนกัน

@RequestMapping("/participant/activityForEvent") 
public ActivitiesT getActivityForGuiEventId() throws Exception {
    ActivitiesT activitiesT = participantService.getActivity();
    // Create a custom Activity POJO and return it
    return new Activity(activitiesT.id, activitiesT.title);
}

POJO ที่กำหนดเองของกิจกรรม:

public class Activity implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public int id;
    public String title;
     //etc.

ข้อความแสดงข้อผิดพลาด

HTTP Status 500 - Could not write JSON: could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy - 

ไม่มีเซสชัน (ผ่านห่วงโซ่การอ้างอิง: com.myapp")

บางสิ่งที่ควรทราบ:

  • วัตถุทั้งสองใช้ Serializable ก็ไม่เป็นไร
  • ปัญหาไม่ใช่ DAO ฉันเห็นว่า DAO ส่งคืนข้อมูลที่ถูกต้องสำหรับทั้งคู่เสมอ เราสามารถเพิกเฉยต่อส่วน DAO ได้
  • คอนโทรลเลอร์มีคำอธิบายประกอบด้วย @RestController ดังนั้นจึงเอาต์พุต JSON เสมอ ฉันไม่ต้องการ ResponseBody หรือแท็กที่เก่ากว่า

มีความคิดใด ๆ เกี่ยวกับปัญหาที่อาจเกิดขึ้น? ปัญหาเกิดขึ้นดังนี้:

  • ฉันไม่สามารถส่งคืน JSON จากวิธี RestController บน @Entity POJO ที่สร้างโดย Hibernate ได้
  • แต่ฉันสามารถส่งคืน JSON จากวิธี RestController บน POJO ที่กำหนดเองของฉันเองได้

person gene b.    schedule 18.12.2017    source แหล่งที่มา
comment
คุณช่วยระบุข้อยกเว้นที่ถูกส่งออกไป (500 Internal Server Error) ได้ไหม   -  person lzagkaretos    schedule 18.12.2017
comment
ไม่มีข้อยกเว้นเกิดขึ้นบนฝั่งเซิร์ฟเวอร์ ตัวควบคุมจะเสร็จสิ้นเป็นตกลง ฉันเห็นข้อผิดพลาดเซิร์ฟเวอร์ภายใน 500 ข้อใน Firebug เท่านั้น เมื่อฉันไปที่ AJAX JS บนฝั่งไคลเอ็นต์   -  person gene b.    schedule 18.12.2017
comment
500 Internal Server Error บ่งชี้ว่ามีบางอย่างเกิดขึ้นที่ฝั่งเซิร์ฟเวอร์ ฉันเคยเห็นปัญหาประเภทนี้ในการทำให้วัตถุขนาดใหญ่เป็นอนุกรม ActivitiesT เป็นวัตถุที่เรียบง่ายหรือซับซ้อน (แค่เดา) โดยมีข้อยกเว้นบางประเภทเกิดขึ้นหลังจากที่ตัวควบคุมส่งคืนค่า   -  person lzagkaretos    schedule 18.12.2017
comment
ฉันได้รับข้อความแสดงข้อผิดพลาดในขณะนี้ นี่คือ: HTTP Status 500 - Could not write JSON: could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy - no Session (through reference chain: com.myapp")   -  person gene b.    schedule 18.12.2017
comment
บางทีใน Entity อาจมีการเริ่มต้น Lazy อยู่ และเมื่อ Jackson พยายามเข้าถึงคุณสมบัตินี้ รายการต่างๆ ก็ไม่มีธุรกรรมใด ๆ ให้เลือก คุณช่วยตรวจสอบได้ไหม?   -  person lzagkaretos    schedule 18.12.2017
comment
ใช่ ดูเหมือนว่ามีเธรดอยู่ที่นี่: stackoverflow.com/questions/26957554/ คำอธิบายคือสิ่งนี้จะเกิดขึ้นเมื่อคุณส่งคืนวัตถุผ่าน @Responsebody (หรือในเนื้อหาการตอบสนองเคสของคุณทาง @RestController) และวัตถุกำลังถูกทำให้เป็นอนุกรม แต่มีลูกอยู่ในคอลเลกชัน LAZY ที่ยังไม่มีการอ้างอิง เมื่อคุณอยู่ในตัวควบคุมของคุณ จะไม่มีการทำธุรกรรมใด ๆ ที่ใช้งานอยู่ซึ่งจะอำนวยความสะดวกในการดึงข้อมูลอีกต่อไป   -  person gene b.    schedule 18.12.2017
comment
ใช่ ฉันเชื่อว่านี่คือปัญหา :) ขอให้โชคดี   -  person lzagkaretos    schedule 18.12.2017


คำตอบ (1)


เมื่อแจ็คสันเตรียมการตอบกลับ แจ็คสันจะพยายามแปลงคลาสโมเดลเป็น JSON แบบวนซ้ำ ตัวอย่างเช่น หากคุณมีความสัมพันธ์ระหว่างแผนกและพนักงานที่มีความสัมพันธ์แบบหนึ่งต่อกลุ่ม แจ็คสันจะใช้เมธอด getEmployees() ใน Department.java เพื่อเตรียมการตอบกลับ แต่ getEmployees() วิธีการนี้ต้องใช้โหมดไฮเบอร์เนตเพื่อดำเนินการค้นหาอื่นเพื่อดึงบันทึกพนักงานจากฐานข้อมูลเนื่องจากการโหลดแบบ Lazy แต่เซสชั่นได้ถูกปิดไปแล้ว ดังนั้นคุณจะได้รับข้อผิดพลาดนี้ เพื่อหลีกเลี่ยงปัญหานี้ ให้ใช้ DTO แทนคลาสโมเดลจริงเสมอ และสิ่งเดียวกับที่คุณพูดถึง - วัตถุโดเมนที่ส่งคืนจาก RestController ทำให้เกิดข้อผิดพลาด AJAX Custom Model Object ใช้งานได้

person Dhiraj Ray    schedule 19.12.2017
comment
ใช่ เรากำลังใช้ POJO ธรรมดาสำหรับวิธีการส่งคืน JSON ทั้งหมด ขอบคุณ - person gene b.; 19.12.2017