2016-11-04 72 views
0

我在德春啓動反序列化類的問題。當我的控制器試圖反序列化它時,它會崩潰。這裏是類:反序列化JSON從休眠

@Entity 
@Table(name="trash_cans") 
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property="id") 
public class TrashCan { 
    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(name="TRASH_CAN_ID") 
    long id; 

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

    @ManyToOne 
    @JoinColumn(name="PLACE_ID") 
    private Place place; 

    @OneToMany(mappedBy="trashCan", targetEntity=TrashMeter.class, fetch=FetchType.LAZY) 
    private List<TrashCan> trashMeterList; 

    @OneToMany(mappedBy="trashCan", targetEntity=TrashSensor.class, fetch=FetchType.LAZY) 
    private List<TrashSensor> trashSensorList; 

    public TrashCan() {  
    } 

    public TrashCan(long id, String name) { 
     super(); 
     this.id = id; 
     this.name = name; 
    } 

    [getters and setters] 
} 

這取決於這一個:

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

    @Id 
    @Column(name="id") 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private long id; 

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

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

    @ManyToOne 
    @JoinColumn(name="TRASH_CAN_ID") 
    private TrashCan trashCan; 

    @OneToMany(mappedBy = "trashSensor", targetEntity = Measurement.class, fetch = FetchType.LAZY) 
    private List<Measurement> measurementList; 

    public TrashSensor() { 
     super(); 
    } 

和垃圾傳感器取決於這個類:

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

    @Id 
    @Column(name="id") 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private long id; 

    @Column(name="value") 
    private float value; 

    @Column(name="last_measure") 
    private LocalDateTime dateTime; 

    @ManyToOne 
    @JoinColumn(name="trash_sensor_id") 
    private TrashCan trashSensor; 

    public Measurement() { 
    } 

} 

我的Controler:

@RequestMapping(value="/trashCan", method=RequestMethod.GET) 
    public ResponseEntity<Iterable<TrashCan>> getPlaces(){ 
     Iterable<TrashCan> trashCanIterable = trashCansRepository.findAll(); 

     return new ResponseEntity<>(trashCanIterable, HttpStatus.OK); 
    } 

當我打電話給web服務時,我得到這個呃ROR:

Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: could not deserialize (through reference chain: java.util.ArrayList[0]-br.com.simplepass.cleanerway.domain.TrashCan["trashSensorList"]-org.hibernate.collection.internal.PersistentBag[0]-br.com.simplepass.cleanerway.domain.TrashSensor["measurementList"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not deserialize (through reference chain: java.util.ArrayList[0]-br.com.simplepass.cleanerway.domain.TrashCan["trashSensorList"]-org.hibernate.collection.internal.PersistentBag[0]-br.com.simplepass.cleanerway.domain.TrashSensor["measurementList"])

我無法解釋這個錯誤=/。任何有關這個問題的幫助非常感謝。當您使用實體之間的關係

@OneToMany(mappedBy = "trashSensor", targetEntity = Measurement.class, fetch = FetchType.LAZY) 
@JsonIgnore 
private List<Measurement> measurementList; 

回答

1

你是因爲你的JSON是進入一個循環,來避免這種情況,使用@JsonIgnore註解收到此錯誤。想象一下,您的垃圾箱已鏈接到垃圾桶。而你的垃圾鏈接到它的包裝 - 垃圾桶。所以你試圖序列化TrashCan實體,你也要序列化垃圾桶。然後當你正在序列化垃圾桶時,垃圾桶再次被序列化。等等。這是一個循環。您可以在每個可能導致循環的實體上使用@JsonIgnore

@JsonIgnore 
@ManyToOne 
@JoinColumn(name="PLACE_ID") 
private Place place; 

@JsonIgnore 
@OneToMany(mappedBy="trashCan", targetEntity=TrashMeter.class, fetch=FetchType.LAZY) 
private List<TrashCan> trashMeterList; 

@JsonIgnore 
@OneToMany(mappedBy="trashCan", targetEntity=TrashSensor.class, fetch=FetchType.LAZY) 
private List<TrashSensor> trashSensorList; 

但這是一個壞方法。強烈建議爲序列化/反序列化使用DTO(數據傳輸對象)模式。它也給你更多的靈活性。如果您需要trashMeterListtrashSensorList響應然後按照這個答案你可以閱讀一下here

+0

是的...這是不是唯一的place..you必須找出更多的映射,其進入循環,並添加相應@JsonIgnore –

+0

感謝快速回復! 如果我這樣做,我將無法使用measurementList,對不對?我需要這個depency ...所以我不能使用@JsonIgnore –

+0

然後使用@JsonIgnore上measurementList映射 –

1

它發生:

+0

馬克西姆,感謝您的閱讀,這是一個非常不錯的主意。我需要這些名單,所以我把@JsonIgonre垃圾桶內,並TrashSensor在映射對象。 很抱歉,但我就是不能看到DTO是怎麼回事幫我...這個控制器的目的是爲了從數據庫中獲取數據,從POJO中直接得到它看起來非常好。無論如何,框架幾乎是在做所有事情。 你覺得呢? –

+0

@LeandroBorgesFerreira,DTO被認爲是最佳實踐。序列化POJO是一個糟糕的代碼。在你的情況下,如果你的應用程序不是很大,並且它不會更大,你可以序列化它們。但是,想想,如果你想添加你的驗證,或者你決定在其他地方提供不完整的實體,你真的需要DTO來改變你的應用程序中任何地方的特定情況下的序列化。例如,您可以將所有關係留在完整的實體中,並根據您對任何控制器的需要創建並序列化特殊的DTO。此外,它使您的模型在大型應用程序中更加清潔。 –

0

由於休眠延遲加載,無會話,而deserialisation,你得到這個例外。

要解決只是改變你的控制器:

@RequestMapping(value="/trashCan", method=RequestMethod.GET) 
    public ResponseEntity<Iterable<TrashCan>> getPlaces(){ 
     Iterable<TrashCan> trashCanIterable = trashCansRepository.findAll(); 
     List<TrashCan> responseList = new ArrayList<TrashCan>(trashCanIterable.size()) 
     while(trashCanIterable.hasNext()){ 
      TrashCan trashCan = trashCanIterable.next(); 
      for(TrashMeter trashMeter : trashCan.trashMeterList){ 

      } 
      for(TrashSensor trashSensor : trashCan.trashSensorList){ 

      } 
      responseList.add(trashCan); 
     } 
     return new ResponseEntity<>(responseList, HttpStatus.OK); 
    }