2016-11-04 68 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); 
    }