【问题标题】:Could not write JSON: Could not set field value [t] by reflection无法写入 JSON:无法通过反射设置字段值 [t]
【发布时间】:2019-05-15 15:03:46
【问题描述】:

我正在开发一个 Spring Boot 2.0.5.RELEASE 项目。 我在 Oracle 数据库中有一个字段声明为 CHAR(1),使用 JPA 转换器如下:

public class CharToBooleanConverter implements AttributeConverter<String, Boolean> {
    @Override
    public Boolean convertToDatabaseColumn(String s) {
        return s.equalsIgnoreCase("t");
    }

    @Override
    public String convertToEntityAttribute(Boolean aBoolean) {

        if(aBoolean.equals(true)){
            return "t";
        } else {
            return "f";
        }
    }
}

这个转换器在我的StructureElement 类中使用了两次:

@Entity
@Table(name = "OBS_STRUCTURE_ELEMENT2")
@SequenceGenerator(name = "structure_element_seq", sequenceName = "structure_element_seq", allocationSize = 1)
public class StructureElement {

    @Id
    @Column(name = "NO_ELEMENT")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "structure_element_seq")
    private long id;

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

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

    @Column(name = "SUITE")
    private int sequence;

    @Column(name = "OPTIONNEL")
    @Convert(converter = CharToBooleanConverter.class)
    private boolean optional;

    @Column(name = "REPETITIF")
    @Convert(converter = CharToBooleanConverter.class)
    private boolean repetitive;

    @ManyToOne
    @JoinColumn(name = "NOM_STRUCTURE_TYPE")
    private Structure typeStructure;

    @Embedded
    private PersistenceSignature signature;
}

问题是,当我尝试通过 RestController 发送 Structure 时,我在控制台中收到以下信息:

已解决 [org.springframework.http.converter.HttpMessageNotWritableException:无法写入 JSON:无法通过反射设置字段值 [t] 值:be.solodoukhin 的 [class be.solodoukhin.domain.StructureElement.optional] 设置器。 domain.StructureElement.optional;嵌套异常是 com.fasterxml.jackson.databind.JsonMappingException:无法通过反射设置字段值 [t] 值:be.solodoukhin.domain.StructureElement.optional 的 [class be.solodoukhin.domain.StructureElement.optional] 设置器(通过参考链:be.solodoukhin.domain.Structure["elements"])]

回复500 Internal Server Error

这是我的方法:

@RestController
@RequestMapping("/structure")
public class StructuresController {
    @GetMapping("/{name}")
    public ResponseEntity<Structure> getOne(@PathVariable("name") String name)
    {
        LOGGER.info("Call to StructuresController.getOne with name = " + name);
        Optional<Structure> found = this.structureRepository.findById(name);
        if(found.isPresent()){
            return ResponseEntity.ok(found.get());
        }
        else
        {
            return ResponseEntity.badRequest().body(null);
        }
    }
}

我尝试使用休眠特定注释@Type(type = "true_false")。它可以工作,但这会在数据库中产生一个大写的TF

我尝试使用 link 编写一个扩展 com.fasterxml.jackson.databind.ser.std.StdSerializer 的 JSON 序列化程序,但没有成功。

【问题讨论】:

  • 与问题无关,但if(aBoolean.equals(true)) 是多余的。 if (aBoolean) 已经足够了(因为布尔值已经验证为真/假)
  • 数据库中的 T 和 F 不能大写还有什么原因吗?
  • @Codeer 我可以使用大写值,但我想知道是否有不接触数据库的解决方案...

标签: java json spring hibernate jackson


【解决方案1】:

你的转换器是不是弄错了?您的 convertToDatabaseColumn 已从字符串变为布尔值。当然,您希望它从布尔值变为字符串。而convertToEntityAttribute 从字符串到布尔值。

我怀疑转换返回的值是“t”或“f”,然后不能将其放入实体的布尔字段中。

我觉得应该是……

public class CharToBooleanConverter implements AttributeConverter<Boolean, String> {
    @Override
    public Boolean convertToEntityAttribute(String s) {
        return s != null && s.equalsIgnoreCase("t");
    }

    @Override
    public String convertToDatabaseColumn(Boolean aBoolean) {
        return (aBoolean != null && aBoolean) ? "t" : "f";
    }
}

【讨论】:

    猜你喜欢
    • 2019-04-22
    • 2014-10-07
    • 1970-01-01
    • 2015-06-15
    • 2011-06-25
    • 2023-04-05
    • 2010-09-14
    • 2020-06-10
    • 2020-07-16
    相关资源
    最近更新 更多