我有两个实体UserCandidat,其中Candidat扩展了类User,如下所示:

用户实体:

@Entity
@Table(name="users")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TYPE_USER",discriminatorType=DiscriminatorType.STRING,length=2)

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,include=JsonTypeInfo.As.PROPERTY,property="type")
@JsonSubTypes({
    @Type(name="UC",value=Candidat.class)
})

@XmlSeeAlso({Candidat.class})
public class User implements Serializable {
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long codeUser;
//other code ...


候选实体:

@Entity
@DiscriminatorValue("UC")
@XmlType(name = "UC")
public class Candidat extends User {
    private String codeMassar;


并保存一个新的Candidat,我将此存储库方法称为:

candidatRepository.save()


来自:

public interface CandidatRepository extends JpaRepository<Candidat, String> {

}


这是我的rest服务,它调用save方法:

@RequestMapping(value = "/candidats", method = RequestMethod.POST)
public Candidat saveCandidat(@RequestBody Candidat candidat) throws Exception {
    return candidatMetier.saveCandidat(candidat);
}


问题是当我要保存新的Candidat时,如下所示:

{
  "username": "User",
  "password": "123456",
  "email": "[email protected]"
}


我收到一条错误消息:


无法读取HTTP消息:
org.springframework.http.converter.HttpMessageNotReadableException:
无法读取文件:预期的凭证(END_OBJECT)
FIELD_NAME:缺少包含类型ID(用于
org.capvalue.fme.domain.Candidat类)


我从中了解到,我必须在要发送的JSON对象中指定类型,但是我认为这不是必需的,因为我保存了具有Candidat的新@DiscriminatorValue("UC"),因此当其saveUser表中,它将自动用type='UC'保存。

我该如何解决?

最佳答案

我从中了解到,我必须在json中指定类型
我发送的对象


由于已添加@JsonTypeInfo,因此应使用type字段指定对象实例的实际类。例如,如果将type字段设置为UC,Jackson将创建一个Candidat类的实例。


但我认为没有必要,因为我保存了一个新的Candidat,
具有@DiscriminatorValue(“ UC”),因此将其保存在User表中时
它会自动以type ='UC'保存。


@DiscriminatorValue将由您的JPA提供程序处理。相反,@JsonTypeInfo是Jackson的概念,所以不!您不能指望JPA @DiscriminatorValue可以帮助Jackson确定对象实例的实际类型。

您应该以JSON表示形式发送type信息,或者从@JsonTypeInfo类中删除@JsonSubTypesUser。我猜想删除Jackson类型注释是更好的方法,因为您在以下位置使用了实际的子类:

public Candidat saveCandidat(@RequestBody Candidat candidat) { ... }


另外,尝试定义一些DTO并将其作为REST端点返回值返回。这种方法的一个优点是,您的Jackson和JPA元数据是分开的,因此可以避免这些问题。

08-08 02:09