使用 Spring 数据 REST 的 JsonMappingException:当 @Id 从正在映射的列表中删除时选择了错误的序列化程序

JsonMappingException using Spring Data REST: Selects wrong serializer when @Id is removed from the list that that is being mapped

我创建了一个 project on gitlab(url),我想在其中使用 Spring Data REST 来保存和公开一些传感器数据。使用 HAL 浏览器进行测试时,持久化到 PostgreSQL 数据库没有问题,但是 SensorReading GET 给我带来了一些麻烦:

Could not write JSON: java.lang.Integer cannot be cast to java.lang.Double; nested exception is com.fasterxml.jackson.databind.JsonMappingException: java.lang.Integer cannot be cast to java.lang.Double (through reference chain: org.springframework.hateoas.Resources[\"_embedded\"]>java.util.Collections$UnmodifiableMap[\"sensorReadings\"]>java.util.ArrayList[0]>org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module$PersistentEntityResourceSerializer[\"content\"]->net.smurfz.kado.models.SensorReading[\"sensorId\"])

我@Entity-class中的代码(net.smurfz.kado.models.SensorReading):

@Entity
public class SensorReading {

    @Id
    @org.springframework.data.annotation.Id
    @SequenceGenerator(name = "sensor_reading_id_seq",
            sequenceName = "sensor_reading_id_seq",
            allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE,
            generator = "sensor_reading_id_seq")
    @Column(updatable = false)
    private Integer id;

    @NotNull
    private Integer sensorId;

    @NotNull
    private double reading;

    @Column(name = "created_date")
    @ReadOnlyProperty
    private Date created;

    public SensorReading() {
    }

    public SensorReading(Integer sensorId, double reading) {
        this.sensorId = sensorId;
        this.reading = reading;
    }

    public Integer getId() {
        return id;
    }

    public Integer getSensorId() {
        return sensorId;
    }

    public void setSensorId(Integer sensorId) {
        this.sensorId = sensorId;
    }

    public double getReading() {
        return reading;
    }

    public void setReading(double reading) {
        this.reading = reading;
    }

    public Date getCreated() {
        return created;
    }

    @PrePersist
    protected void onCreate() {
        created = new Date();
    }
}

和我的@RepositoryRestResource-class (net.smurfz.kado.repositories.SensorReadingRepository):

@RepositoryRestResource
public interface SensorReadingRepository extends CrudRepository<SensorReading, Integer> {
    List<SensorReading> findTop30BySensorIdOrderByCreatedDesc(Integer sensorId);
    Long countAllBySensorId(Integer sensorId);
    SensorReading findFirstBySensorIdOrderByCreatedDesc(Integer sensorId);
    Page<SensorReading> findAllBySensorId(Integer sensorId, Pageable pageable);
}

现在,我尊敬的同事设法发现的快速修复方法是移动:

        @Id
        @org.springframework.data.annotation.Id
        @SequenceGenerator(name = "sensor_reading_id_seq",
                sequenceName = "sensor_reading_id_seq",
                allocationSize = 1)
        @GeneratedValue(strategy = GenerationType.SEQUENCE,
                generator = "sensor_reading_id_seq")
        @Column(updatable = false)
        private Integer id;

在所有其他字段声明下。

当 BeanSerializerFactory-class 尝试定义要使用的序列化程序时,此错误会在某处发生。我的工作理论是它最初识别 4 个字段(4 个列表),然后过滤掉不被序列化的 id(3 个列表),但决定在第二个列表中使用第一个列表中的索引 (1-3) ,导致 Integer 字段获得下面定义的双字段的序列化程序。

这是一个不需要的肮脏黑客,因为我真的不知道这可能会影响我想知道的其他事情:

a) 为什么会这样?

b) 应该做些什么来避免这个错误?

URL 上面的链接直接指向实施 id-fix 之前的提交。

引用@Damien 的评论:

I didnt no - based on this jira - github.com/spring-projects/spring-boot/issues/9756. Changing the version to 2.0.0.BUILD-SNAPSHOT resolves the issue. – Damien

springBootVersion = '2.0.0.BUILD-SNAPSHOT' 解决了这个问题。