Java 当序列化为JSON时,Spring数据Rest会展平对象层次结构
我们正在一个项目中使用SpringDataREST2.4.2.RELEASE(使用SpringBoot,JPA/Hibernate)。 我们有一个具有以下结构的数据库模型: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,“
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映射吗