Java 当序列化为JSON时,Spring数据Rest会展平对象层次结构

Java 当序列化为JSON时,Spring数据Rest会展平对象层次结构,java,json,spring,spring-data,spring-data-rest,Java,Json,Spring,Spring Data,Spring Data Rest,我们正在一个项目中使用SpringDataREST2.4.2.RELEASE(使用SpringBoot,JPA/Hibernate)。 我们有一个具有以下结构的数据库模型: table A: name: string b -> B //meaning a reference to table B table B: x: number y: number 我们需要使用REST/JSON将实体A公开为: {“name”:“myName”,“position”:{“x”:1,“

我们正在一个项目中使用SpringDataREST2.4.2.RELEASE(使用SpringBoot,JPA/Hibernate)。 我们有一个具有以下结构的数据库模型:

table A:
  name: string
  b -> B //meaning a reference to table B
table B:
  x: number
  y: number
我们需要使用REST/JSON将实体A公开为:

{“name”:“myName”,“position”:{“x”:1,“y”:3}
我们已经为Position提供了java类:

公共类职位{
@列(nullable=true)
@JsonProperty
私人浮动x;
@列(nullable=true)
@JsonProperty
私人游船;
}
因此,我们使用JPA注释创建映射到数据库表的A和B类,但我们在注释中使用直接访问B的获取程序
@JsonProperty
公开了一个属性
position

@RepositoryRestResource
公共接口ARepository扩展了JpaRepository{
}
@实体
公共A类{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@JsonProperty
私人长id;
@多通(级联=级联类型.ALL)
@杰索尼奥雷
私人B,;
@JsonProperty
私有字符串名称;
@JsonProperty
公共位置getPosition(){
如果(b==null){
b=新的b();
}
返回b.getPosition();
}
@JsonProperty
公共无效设置位置(位置){
if(this.b==null){
this.b=新的b();
}  
本.b.设定位置(位置);
}
}
还有我的B对象,我不想在REST API中公开它:

@实体
公共B级{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@JsonProperty
私人长id;
@嵌入
@列(nullable=true)
私人职位;
位置getPosition(){
返回位置;
}
无效设置位置(位置){
这个位置=位置;
}
}
使用此结构,我可以将新对象毫无问题地发布到API中:

curl -XPOST -H 'Accept: application/json' -H 'Content-type: application/json' localhost:12000/as -d '
{ "name": "aName", "position": {"x":1, "y":2}}'
这将创建一个对象:

{
  "name" : "aName",
  "position" : {
    "x" : 1.0,
    "y" : 2.0
  },
  "_links" : {
    "self" : {
      "href" : "http://127.0.0.1:12000/as/5"
    },
    "a" : {
      "href" : "http://127.0.0.1:12000/as/5"
    }
  }
}
但当我尝试使用PUT更新对象时:

curl -XPUT -H 'Accept: application/json' -H 'Content-type: application/json' localhost:12000/as/5 -d '
{"name": "aName", "position": {"x":4, "y":3}}'
我得到这个错误

{“原因”:{“原因”:{“原因”:null,“消息”:null},“消息”:“无法读取有效负载!”;嵌套异常为java.lang.NullPointerException“}”,消息:“无法从请求中读取类型为io.epiclabs.flex.network.A的对象!;嵌套异常为org.springframework.http.converter.httpMessageNodeAbleException:无法读取负载!;嵌套异常为java.lang.NullPointerException”

调试SpringDataREST代码时,我发现问题出在
org.springframework.data.rest.webmvc.DomainObjectReader.doMerge
第192行

PersistentProperty<?> property = mappedProperties.getPersistentProperty(fieldName);

if (associationLinks.isLinkableAssociation(property)) {
        continue;
}

PersistentPropertyAccessor accessor = entity.getPropertyAccessor(target);
Object nested = accessor.getProperty(property);
PersistentProperty=mappedProperties.getPersistentProperty(fieldName);
if(associationLinks.isLinkableAssociation(属性)){
继续;
}
PersistentPropertyAccessor访问器=entity.getPropertyAccessor(目标);
对象嵌套=accessor.getProperty(属性);
属性
为空,因为对象中没有
位置
的映射信息(mappedProperties仅从JPA映射信息中获取)

它似乎只是在更新(PUT)时才这样做,而在POST中,它只是获取POJO和Jackson映射信息来设置位置对象

我的问题是:在序列化/反序列化时,如何配置映射,使Jackson模块从JSONProperties注释中获取信息,而不是JPA实体信息

在不改变数据库模型的情况下,我们能以不同的方式进行json映射吗